Ashar086 commited on
Commit
f060530
·
verified ·
1 Parent(s): 7e6bc54

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -119
app.py CHANGED
@@ -1,140 +1,174 @@
1
- import requests
2
  import streamlit as st
 
 
 
 
 
 
3
 
4
- # Set your API key and endpoint here
5
- API_KEY = "3fbfe25109b647efb7bf2f45bd667163" # Replace with your actual API key
6
- API_URL = "https://aimlapi.com/" # Replace with the actual API endpoint
7
 
8
- def call_ai_ml_api(prompt):
9
- headers = {
10
- "Authorization": f"Bearer {API_KEY}",
11
- "Content-Type": "application/json",
12
- }
13
- payload = {
14
- "model": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
15
- "prompt": prompt,
16
- "max_new_tokens": 500,
17
- "temperature": 0.7,
18
- }
19
-
20
- response = requests.post(API_URL, headers=headers, json=payload)
21
-
22
- if response.status_code == 200:
23
- return response.json()["generated_text"]
24
- else:
25
- st.error("Failed to generate response from AI/ML API.")
26
- return ""
27
 
28
- def call_llama_for_response(clauses_data):
29
- prompt = "As an AI assistant specializing in contract analysis, draft a professional and courteous response to a contract drafter based on the following clause analyses and decisions:\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
- for clause in clauses_data:
32
- prompt += f"Clause: {clause['agent']}\n"
33
- prompt += f"Analysis: {clause['analysis']}\n"
34
- prompt += f"Recommendation: {clause['recommendation']}\n"
35
- prompt += f"Decision: {clause['action']}\n"
36
- if clause['action'] == 'Negotiate':
37
- prompt += f"Negotiation points: {clause['negotiation_points']}\n"
38
- prompt += "\n"
39
 
40
- prompt += "Draft a response that addresses each clause, explaining our position on acceptance, rejection, or negotiation. The tone should be professional, courteous, and constructive."
41
-
42
- response = call_ai_ml_api(prompt)
43
- return response
44
-
45
- st.title("Contract Negotiation Assistant")
46
 
47
- # Use session state to store the uploaded file and analysis results
48
- if 'uploaded_file' not in st.session_state:
49
- st.session_state.uploaded_file = None
50
- if 'analysis_results' not in st.session_state:
51
- st.session_state.analysis_results = None
 
 
 
 
52
 
53
- # File uploader
54
- uploaded_file = st.file_uploader("Upload Contract", type=["pdf", "docx"])
 
 
 
 
 
 
 
55
 
56
- # If a new file is uploaded, update the session state and clear previous results
57
- if uploaded_file is not None and uploaded_file != st.session_state.uploaded_file:
58
- st.session_state.uploaded_file = uploaded_file
59
- st.session_state.analysis_results = None
 
 
 
 
60
 
61
- # If we have an uploaded file, process it
62
- if st.session_state.uploaded_file is not None:
63
- # Simulate analysis of the uploaded contract (you may replace this with your actual analysis logic)
64
- # For now, we just mock some analysis results for demonstration purposes
65
- st.write("Contract uploaded successfully. Analyzing...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
- # Example of simulated analysis results
68
- st.session_state.analysis_results = {
69
- "crew_analysis": {
70
- "final_recommendation": {
71
- "tasks_output": [
72
- {
73
- "agent": "Clause 1",
74
- "pydantic": {
75
- "analysis": "This clause limits liability.",
76
- "recommendation": "Consider revising for fairness."
77
- }
78
- },
79
- {
80
- "agent": "Clause 2",
81
- "pydantic": {
82
- "analysis": "This clause outlines payment terms.",
83
- "recommendation": "This is acceptable."
84
- }
85
- }
86
- ]
87
- }
88
- }
89
- }
90
 
91
- # If we have analysis results, display them and allow user interaction
92
- if st.session_state.analysis_results is not None:
93
- data = st.session_state.analysis_results
94
- crew_analysis = data.get("crew_analysis", {})
95
 
96
- # Extract the tasks_output from the nested structure
97
- tasks_output = crew_analysis.get("final_recommendation", {}).get("tasks_output", [])
98
 
99
- clauses_data = []
100
- for task in tasks_output:
101
- agent = task.get("agent", "")
102
- if task.get("pydantic"):
103
- clause_analysis = task["pydantic"].get("analysis", "")
104
- recommendation = task["pydantic"].get("recommendation", "")
105
-
106
- st.subheader(f"Clause: {agent}")
107
- st.write("Analysis:")
108
- st.write(clause_analysis)
109
- st.write("Recommendation:")
110
- st.write(recommendation)
111
 
112
- action = st.selectbox(
113
- f"Action for {agent}",
114
- ["Accept", "Negotiate", "Reject"],
115
- key=f"action_{agent}"
116
- )
117
- negotiation_points = ""
118
- if action == "Negotiate":
119
- negotiation_points = st.text_area("Enter your negotiation points:", key=f"negotiate_{agent}")
120
-
121
- clauses_data.append({
122
- "agent": agent,
123
- "analysis": clause_analysis,
124
- "recommendation": recommendation,
125
- "action": action,
126
- "negotiation_points": negotiation_points
127
- })
128
-
129
- st.markdown("---") # Add a separator between clauses
 
130
 
131
  # Finalize Contract button
132
  if st.button("Finalize Contract"):
133
- with st.spinner("Generating response..."):
134
- response_to_drafter = call_llama_for_response(clauses_data)
135
- st.subheader("Response to Contract Drafter:")
136
- st.text_area("", response_to_drafter, height=400)
137
- st.success("Contract negotiation completed. Response generated for review.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
 
 
139
  else:
140
  st.write("Please upload a contract to begin the analysis.")
 
 
1
  import streamlit as st
2
+ import json
3
+ import fitz # PyMuPDF
4
+ import docx # python-docx
5
+ import os
6
+ import re
7
+ import openai
8
 
9
+ api_key = '3fbfe25109b647efb7bf2f45bd667163'
10
+ openai.api_key = api_key
11
+ openai.api_base = "https://api.aimlapi.com"
12
 
13
+ def call_ai_api(prompt, max_tokens=1000):
14
+ """
15
+ Function to call the 3rd party Llama API.
16
+ """
17
+ try:
18
+ response = openai.ChatCompletion.create(
19
+ model="meta-llama/Llama-3.2-3B-Instruct-Turbo", # Using Llama-3.2 model
20
+ messages=[
21
+ {
22
+ "role": "user",
23
+ "content": prompt # Directly use the prompt string
24
+ }
25
+ ],
26
+ max_tokens=max_tokens,
27
+ )
28
+ return response.choices[0].message["content"]
29
+ except Exception as e:
30
+ print(f"An error occurred while calling the API: {str(e)}")
31
+ return None
32
 
33
+ def extract_json(text):
34
+ """
35
+ Try to extract JSON data from a text string using a regular expression.
36
+ """
37
+ json_match = re.search(r'{.*}', text, re.DOTALL)
38
+ if json_match:
39
+ return json_match.group(0)
40
+ return None
41
+
42
+ def chunk_text(text, max_chunk_size=3000):
43
+ """
44
+ Split the text into chunks based on a maximum size.
45
+ """
46
+ chunks = []
47
+ words = text.split()
48
+ current_chunk = []
49
 
50
+ for word in words:
51
+ current_chunk.append(word)
52
+ if len(' '.join(current_chunk)) > max_chunk_size:
53
+ chunks.append(' '.join(current_chunk[:-1]))
54
+ current_chunk = [word]
 
 
 
55
 
56
+ if current_chunk:
57
+ chunks.append(' '.join(current_chunk))
58
+
59
+ return chunks
 
 
60
 
61
+ def extract_text_from_pdf(file_content):
62
+ """
63
+ Extract text from a PDF file using PyMuPDF.
64
+ """
65
+ pdf_document = fitz.open(stream=file_content, filetype="pdf")
66
+ text = ""
67
+ for page in pdf_document:
68
+ text += page.get_text()
69
+ return text
70
 
71
+ def extract_text_from_docx(file_content):
72
+ """
73
+ Extract text from a DOCX file using python-docx.
74
+ """
75
+ doc = docx.Document(file_content)
76
+ text = []
77
+ for para in doc.paragraphs:
78
+ text.append(para.text)
79
+ return "\n".join(text)
80
 
81
+ def analyze_contract(file_content, file_type):
82
+ # Extract the text based on the file type
83
+ if file_type == "pdf":
84
+ decoded_content = extract_text_from_pdf(file_content)
85
+ elif file_type == "docx":
86
+ decoded_content = extract_text_from_docx(file_content)
87
+ else:
88
+ decoded_content = file_content.decode('utf-8') # Assuming it's a text file
89
 
90
+ # Chunk the contract content
91
+ chunks = chunk_text(decoded_content, max_chunk_size=3000) # Adjust the size as needed
92
+ analysis_results = {"clauses": []}
93
+
94
+ for chunk in chunks:
95
+ prompt = f"""Analyze the following contract section and provide a detailed breakdown of its clauses, including their titles, content, risk level, and a brief explanation for each. The document content is as follows:
96
+ {chunk}
97
+ Format your response as a JSON object with a 'clauses' key containing an array of clause objects. Each clause object should have 'title', 'content', 'risk_level', and 'explanation' keys. Do not include any extra text, only the JSON output.
98
+ """
99
+ # Call AI API to analyze each chunk
100
+ response = call_ai_api(prompt, max_tokens=2000)
101
+
102
+ # Parse the JSON response
103
+ if response:
104
+
105
+ # Try to extract JSON from the response
106
+ json_data = extract_json(response)
107
+ if json_data:
108
+ try:
109
+ analysis_result = json.loads(json_data)
110
+ if "clauses" in analysis_result:
111
+ analysis_results["clauses"].extend(analysis_result["clauses"])
112
+ else:
113
+ st.warning("The API response did not include any clauses.")
114
+ except json.JSONDecodeError:
115
+ pass
116
+ else:
117
+ st.error("The response did not contain any recognizable JSON.")
118
 
119
+ return analysis_results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
+ st.title("Contract Negotiation Assistant")
 
 
 
122
 
123
+ uploaded_file = st.file_uploader("Upload your contract document", type=["txt", "pdf", "docx"])
 
124
 
125
+ if uploaded_file is not None:
126
+ file_content = uploaded_file.read()
127
+ file_type = uploaded_file.type.split('/')[1] # Get file type (e.g., pdf, docx)
 
 
 
 
 
 
 
 
 
128
 
129
+ st.write("Analyzing contract...")
130
+ analysis_result = analyze_contract(file_content, file_type)
131
+
132
+ if analysis_result and analysis_result.get("clauses"):
133
+ clauses = analysis_result.get("clauses", [])
134
+ clause_decisions = {}
135
+
136
+ for i, clause in enumerate(clauses):
137
+ st.subheader(f"Clause {i + 1}: {clause['title']}")
138
+ st.write(clause['content'])
139
+ st.write(f"Risk Level: {clause['risk_level']}")
140
+ st.write(f"Explanation: {clause['explanation']}")
141
+
142
+ decision = st.radio(f"Decision for Clause {i + 1}", ["Accept", "Negotiate", "Reject"], key=f"decision_{i}")
143
+ clause_decisions[i] = decision
144
+
145
+ if decision == "Negotiate":
146
+ negotiation_points = st.text_area(f"Enter negotiation points for Clause {i + 1}", key=f"negotiation_{i}")
147
+ clause_decisions[f"{i}_points"] = negotiation_points # Save negotiation points
148
 
149
  # Finalize Contract button
150
  if st.button("Finalize Contract"):
151
+ prompt = """As a professional contract negotiator, draft a courteous email response to the contract drafter based on the following decisions:\n\n"""
152
+
153
+ for i, clause in enumerate(clauses):
154
+ decision = clause_decisions[i]
155
+ prompt += f"Clause {i + 1} ({clause['title']}): {decision}\n"
156
+ if decision == "Negotiate":
157
+ prompt += f"Negotiation points: {clause_decisions.get(f'{i}_points', 'No specific points provided.')}\n"
158
+ prompt += "\n"
159
+
160
+ prompt += "Please draft a professional and polite email response addressing these points and suggesting next steps for the negotiation process."
161
+
162
+ response = call_ai_api(prompt)
163
+
164
+ st.subheader("Generated Response:")
165
+ st.write(response)
166
+
167
+ if st.button("Save Response"):
168
+ # Implement saving functionality here
169
+ st.write("Response saved successfully!")
170
 
171
+ else:
172
+ st.write("No clauses found in the contract analysis. Please try again.")
173
  else:
174
  st.write("Please upload a contract to begin the analysis.")