Skip to content

Commit feabe7f

Browse files
committed
Add legalsimplifier example.
1 parent beed68f commit feabe7f

File tree

11 files changed

+415
-0
lines changed

11 files changed

+415
-0
lines changed

examples/legalsimplifier/README.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Legal Simplifier
2+
3+
Legal Simplifier is an application that allows you to simplify legal documents - from terms and conditions of an insrance policy or a business contract. This example also shows how we can summarize contents of a large documents in chunks.
4+
5+
Based on the document you upload, the size can vary and hence mgight find the need to split larger documents into chunks of 10,000 tokens to fit within GTP-4's context window.
6+
7+
## Design
8+
9+
The script consists of three tools: a top-level tool that orchestrates everything, a summarizer that
10+
will summarize one chunk of text at a time, and a Python script that ingests the PDF and splits it into
11+
chunks and provides a specific chunk based on an index.
12+
13+
The summarizer tool looks at the entire summary up to the current chunk and then summarizes the current
14+
chunk and adds it onto the end. In the case of models with very small context windows, or extremely large
15+
documents, this approach may still exceed the context window, in which case another tool could be added to
16+
only give the summarizer the previous few chunk summaries instead of all of them.
17+
18+
## Installation
19+
20+
### Prerequisites
21+
22+
- Python 3.8 or later
23+
- Flask
24+
- Other Python dependencies listed in `requirements.txt`.
25+
26+
### Steps
27+
28+
1. Clone the repository:
29+
30+
``` bash
31+
git clone https://github.com/gptscript-ai/gptscript.git
32+
```
33+
34+
2. Navigate to the `examples/legalsimplifier` directory and install the dependencies:
35+
36+
Python:
37+
38+
```bash
39+
pip install -r requirements.txt
40+
```
41+
42+
Node:
43+
44+
```bash
45+
npm install
46+
```
47+
48+
3. Setup `OPENAI_API_KEY` (Eg: `export OPENAI_API_KEY="yourapikey123456"`). You can get your [API key here](https://platform.openai.com/api-keys).
49+
50+
4. Run the Flask application using `flask run` or `python app.py`
51+
52+
## Usage
53+
54+
1. Open your web browser and navigate to `http://127.0.0.1:5000/`.
55+
2. Use the web interface to upload an a legal document in .pdf format.
56+
3. The application will analyze the document and show a summary.
57+
58+
## Under the hood
59+
60+
Below are the processes that take place when you execute the application:
61+
62+
- The Python app places the uploaded image as `legal.pdf` in the current working directory.
63+
- It then executes `legalsimplifier.gpt` which internally calls `main.py` to split the large document in chunks so that they fit within the token limit of GPT-4's context.
64+
- The analysis will be stored in a `summary.md` document.
65+
- The app will then read this summary file and show the summary on the UI.

examples/legalsimplifier/app.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from flask import Flask, jsonify, render_template, request
2+
import subprocess
3+
import os
4+
5+
app = Flask(__name__)
6+
7+
# Setting the base directory
8+
base_dir = os.path.dirname(os.path.abspath(__file__))
9+
app.config['UPLOAD_FOLDER'] = base_dir
10+
11+
SCRIPT_PATH = os.path.join(base_dir, 'legalsimplifier.gpt')
12+
LEGAL_FILE_NAME = 'legal.pdf' # Uploaded document name
13+
SUMMARY_FILE_NAME = 'summary.md' # The output file name
14+
15+
@app.route('/')
16+
def index():
17+
return render_template('index.html')
18+
19+
@app.route('/upload', methods=['POST'])
20+
def upload_file():
21+
if 'file' not in request.files:
22+
return jsonify({'error': 'No file part'}), 400
23+
file = request.files['file']
24+
if file.filename == '':
25+
return jsonify({'error': 'No selected file'}), 400
26+
if file:
27+
# Process the file here to generate the summary
28+
filename = os.path.join(app.config['UPLOAD_FOLDER'], LEGAL_FILE_NAME)
29+
file.save(filename)
30+
summary = process_file(file)
31+
return jsonify({'summary': summary})
32+
33+
def process_file(file):
34+
try:
35+
# Execute the script to generate the recipe
36+
subprocess.run(f"gptscript {SCRIPT_PATH}", shell=True, check=True)
37+
38+
# Read summary.md file
39+
summary_file_path = os.path.join(app.config['UPLOAD_FOLDER'], SUMMARY_FILE_NAME)
40+
with open(summary_file_path, 'r') as summary_file:
41+
summary = summary_file.read()
42+
43+
# Return summary content
44+
return summary
45+
except Exception as e:
46+
return jsonify({'error': str(e)}), 500
47+
48+
if __name__ == '__main__':
49+
app.run(debug=False)

examples/legalsimplifier/legal.pdf

555 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
tools: legal-simplifier, sys.read, sys.write
2+
3+
You are a program that is tasked with analyizing a legal document and creating a summary of it.
4+
Create a new file "summary.md" if it doesn't already exist.
5+
Call the legal-simplifier tool to get each part of the document. Begin with index 0.
6+
Do not proceed until the tool has responded to you.
7+
Once you get "No more content" from the legal-simplifier stop calling it.
8+
Then, print the contents of the summary.md file.
9+
10+
---
11+
name: legal-simplifier
12+
tools: doc-retriever, sys.read, sys.append
13+
description: Summarizes a legal document
14+
15+
As a legal expert and practicing lawyer, you are tasked with analyzing the provided legal document.
16+
Your deep understanding of the law equips you to simplify and summarize the document effectively.
17+
Your goal is to make the document more accessible for non-experts, leveraging your expertise to provide clear and concise insights.
18+
19+
Get the part of legal document at index $index.
20+
Read the existing summary of the legal document up to this point in summary.md.
21+
Do not leave out any important points focusing on key points, implications, and any notable clauses or provisions.
22+
Do not introduce the summary with "In this part of the document", "In this segment", or any similar language.
23+
Give a list of all the terms and explain them in one liner before writing the summary in the document.
24+
For each summary write in smaller chunks or add bullet points if required to make it easy to understand.
25+
Use headings and sections breaks as required.
26+
Use the heading as "Summary" as only once in the entire document.
27+
Explain terms in simple language and avoid legal terminologies until unless absolutely necessary.
28+
Add two newlines to the end of your summary and append it to summary.md.
29+
30+
If you got "No more content" just say "No more content". Otherwise, say "Continue".
31+
32+
---
33+
name: doc-retriever
34+
description: Returns a part of the text of legal document. Returns "No more content" if the index is greater than the number of parts.
35+
args: index: (unsigned int) the index of the part to return, beginning at 0
36+
37+
#!python3 main.py "$index"

examples/legalsimplifier/main.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import tiktoken
2+
import sys
3+
from llama_index.readers.file import PyMuPDFReader
4+
from llama_index.core.node_parser import TokenTextSplitter
5+
6+
# Loading the legal document using PyMuPDFReader
7+
index = int(sys.argv[1])
8+
docs = PyMuPDFReader().load("legal.pdf")
9+
10+
# Combining text content from all documents into a single string
11+
combined = ""
12+
for doc in docs:
13+
combined += doc.text
14+
15+
# Initializing a TokenTextSplitter object with specified parameters
16+
splitter = TokenTextSplitter(
17+
chunk_size=10000,
18+
chunk_overlap=10,
19+
tokenizer=tiktoken.encoding_for_model("gpt-4-turbo-preview").encode)
20+
21+
pieces = splitter.split_text(combined)
22+
23+
# Checking if the specified index is valid
24+
if index >= len(pieces):
25+
print("No more content")
26+
sys.exit(0)
27+
28+
print(pieces[index])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Flask==2.0.1
2+
tiktoken==0.6.0
3+
llama-index-core==0.10.14
4+
llama-index-readers-file==0.1.6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
body {
2+
padding-top: 20px;
3+
font-family: 'Roboto', sans-serif;
4+
background-color: #ffffff;
5+
}
6+
7+
.navbar {
8+
margin-bottom: 20px;
9+
background-color: #009688; /* Teal color */
10+
}
11+
12+
.navbar-brand, .nav-link {
13+
color: #fff !important;
14+
}
15+
16+
.container-fluid {
17+
max-width: 1200px; /* Adjust based on your preference */
18+
}
19+
20+
.row {
21+
margin: 0;
22+
}
23+
24+
.col-md-6 {
25+
width: 50%;
26+
padding: 20px;
27+
box-sizing: border-box;
28+
}
29+
30+
.form-control, .btn, .custom-file-label {
31+
border-radius: 0; /* Material design doesn't use rounded corners for inputs/buttons */
32+
}
33+
34+
/* Simplified content styling */
35+
#simplified-content {
36+
background-color: #fff;
37+
padding: 20px;
38+
border-radius: 5px;
39+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
40+
}
41+
42+
.loader {
43+
display: none;
44+
border: 4px solid #f3f3f3;
45+
border-top: 4px solid #3498db;
46+
border-radius: 50%;
47+
width: 30px;
48+
height: 30px;
49+
animation: spin 2s linear infinite;
50+
}
51+
@keyframes spin {
52+
0% { transform: rotate(0deg); }
53+
100% { transform: rotate(360deg); }
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
document.addEventListener('DOMContentLoaded', function() {
2+
3+
const randomMessages = [
4+
"Brewing up some simplicity.",
5+
"Decoding legalese.",
6+
"Simplifying complex texts.",
7+
"Turning the complicated into the understandable.",
8+
"Working our magic on your document."
9+
];
10+
11+
// Define uploadFile globally
12+
window.uploadFile = function() {
13+
var form = document.getElementById('uploadForm');
14+
var formData = new FormData(form);
15+
var summaryBlock = document.getElementById('summaryBlock');
16+
var summaryOutput = document.getElementById('documentSummary');
17+
18+
// Display a random message
19+
var messageDiv = document.getElementById('randomMessage');
20+
messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)]; // Display initial random message
21+
var messageInterval = setInterval(function() {
22+
messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)];
23+
}, 5000); // Change message every 5 seconds
24+
25+
fetch('/upload', {
26+
method: 'POST',
27+
body: formData,
28+
})
29+
.then(response => response.json()) // Parse the JSON response
30+
.then(data => {
31+
if(data.summary) {
32+
console.log(data.summary)
33+
var converter = new showdown.Converter()
34+
var parsedHtml = converter.makeHtml(data.summary);
35+
summaryOutput.innerHTML = parsedHtml; // Display the recipe
36+
summaryBlock.style.display='block'
37+
messageDiv.style.display = 'none' // Clear message
38+
39+
// Scroll to the documentSummary div
40+
document.getElementById('documentSummary').scrollIntoView({
41+
behavior: 'smooth', // Smooth scroll
42+
block: 'start' // Align to the top of the view
43+
});
44+
45+
} else if (data.error) {
46+
summaryOutput.innerHTML = `<p>Error: ${data.error}</p>`;
47+
messageDiv.style.display = 'none' // Clear message
48+
}
49+
})
50+
.catch(error => {
51+
console.error('Error:', error);
52+
summaryOutput.innerHTML = `<p>Error: ${error}</p>`;
53+
messageDiv.style.display = 'none' // Clear message
54+
});
55+
};
56+
});

examples/legalsimplifier/summary.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
### Summary
2+
3+
- **Proposal**: When someone shows their willingness to do or not do something to get agreement from another.
4+
- **Promise**: A proposal that has been agreed upon.
5+
- **Promisor and Promisee**: The one making the proposal and the one accepting it, respectively.
6+
- **Consideration**: Something done or not done, or promised to be done or not done, which forms the reason for a party's agreement to a promise.
7+
- **Agreement**: A set of promises forming the reason for each other's agreement.
8+
- **Contract**: An agreement enforceable by law.
9+
- **Voidable Contract**: A contract that can be enforced or nullified at the option of one or more parties.
10+
- **Void Agreement**: An agreement not enforceable by law.
11+
12+
- The document begins by defining key terms related to contracts, such as proposal, promise, consideration, agreement, contract, voidable contract, and void agreement.
13+
- It outlines the process of making a proposal, accepting it, and the conditions under which a proposal or acceptance can be revoked.
14+
- It emphasizes that for a proposal to turn into a promise, the acceptance must be absolute and unqualified.
15+
- The document also explains that agreements become contracts when they are made with free consent, for a lawful consideration and object, and are not declared void.
16+
- Competence to contract is defined by age, sound mind, and not being disqualified by any law.
17+
- The document details what constitutes free consent, including the absence of coercion, undue influence, fraud, misrepresentation, or mistake.
18+
- It specifies conditions under which agreements are void, such as when both parties are under a mistake regarding a fact essential to the agreement.
19+
20+
21+
22+
- Mistakes in contracts are addressed, clarifying that a contract is not voidable just because it was made under a mistake of one party regarding a matter of fact.
23+
- It outlines what considerations and objects are lawful, emphasizing that an agreement's consideration or object is lawful unless it is forbidden by law, defeats the provisions of any law, is fraudulent, involves injury to person or property, or is deemed immoral or opposed to public policy by the court. Any agreement with an unlawful object or consideration is void.
24+
- Examples are provided to illustrate lawful and unlawful considerations and objects in agreements, such as lawful agreements to sell property or make payments under certain conditions, and unlawful agreements involving fraud, employment in public service for payment, and agreements made without the knowledge of a principal that imply fraud.
25+
- It is stated that agreements void if considerations and objects are unlawful in part, highlighting that if any part of a single consideration for one or more objects, or any one or any part of any one of several considerations for a single object, is unlawful, the agreement is void.
26+
- The document explains that an agreement made without consideration is void unless it meets specific exceptions, such as being in writing and registered, made to compensate for something done, or to pay a debt barred by limitation law. Examples are given to illustrate these exceptions, including agreements made out of natural love and affection, to compensate for voluntary actions, or to pay a part of a debt barred by law.- **Novation, Rescission, and Alteration of Contracts**: These terms refer to the replacement of an existing contract with a new one (novation), the cancellation of a contract (rescission), and changes made to the terms of a contract (alteration).
27+
- **Promisee's Rights**: The right of the promisee to dispense with or remit performance, extend time for performance, or accept any satisfaction instead of performance.
28+
- **Voidable Contracts and Rescission**: Details on how a voidable contract can be rescinded, emphasizing the need for the party rescinding to return any benefits received.
29+
- **Obligations under Void Agreements**: If an agreement is found void, any person who has received advantage under such agreement must restore it or compensate for it.
30+
- **Communication of Rescission**: Explains how the rescission of a voidable contract should be communicated.
31+
- **Facilities for Performance**: If a promisee refuses to afford the promisor reasonable facilities for performance, the promisor is excused for non-performance.
32+
- **Necessaries Supplied to Incapable Persons**: Persons who supply necessaries to someone incapable of contracting are entitled to reimbursement from the incapable person's property.
33+
- **Reimbursement for Payment on Another's Behalf**: If someone pays money which another is bound by law to pay, they are entitled to be reimbursed by the other person.
34+
- **Benefit of Non-gratuitous Act**: If someone enjoys the benefit of a non-gratuitous act, they must compensate the person who performed the act.
35+
- **Finder of Goods**: A person who finds goods belonging to another and takes them into custody has the same responsibility as a bailee.
36+
- **Money Paid under Mistake or Coercion**: Any money paid or thing delivered by mistake or under coercion must be returned.
37+
38+
- The document transitions into discussing the legal concept of bailment, which involves the delivery of goods by one person (the bailor) to another (the bailee) for a specific purpose, with the expectation that the goods will be returned or disposed of as per the bailor's instructions.
39+
- It outlines the responsibilities of the bailor, such as disclosing any faults in the goods that could affect their use or expose the bailee to risks. If the bailor fails to disclose such faults, they are liable for any resulting damage to the bailee.
40+
- The bailee's duties are also detailed, including taking care of the bailed goods as a person of ordinary prudence would take care of their own similar goods. The bailee is not liable for loss or damage to the goods if they have taken the proper amount of care as described.
41+
- The document explains various scenarios involving the mixing of the bailor's goods with the bailee's, detailing the outcomes depending on whether the bailor consented to the mixing and whether the goods can be separated after mixing.
42+
- It covers the rights and responsibilities related to expenses incurred during the bailment, the return of goods lent gratuitously, and the termination of bailment under different circumstances.
43+
- The section on bailment concludes with the rights of the bailee to retain the goods until they are compensated for any necessary expenses or services provided in relation to the bailed goods.
44+
45+
46+
47+
- Agents must act in the best interest of their principals, including making good on losses due to their negligence, properly accounting for their actions, and seeking the principal's instructions in difficult situations.
48+
- Agents dealing in the agency's business for their own benefit without the principal's consent may face repudiation of the transaction by the principal, especially if the agent concealed material facts or the dealings were disadvantageous to the principal.
49+
- Principals have the right to any benefits an agent gains from unauthorized dealings in the agency's business.
50+
- Agents can retain from any received sums, the amounts due to them for expenses or services in the agency's business, but must pay the principal any remaining sums.
51+
- Agents are not entitled to remuneration for misconducted business and have a right to retain the principal's property as security for what is owed to them.
52+
- Principals must indemnify agents against consequences of lawful acts or acts done in good faith, but not for criminal acts.
53+
- Contracts made through agents are as enforceable as if made by the principals themselves. However, agents cannot enforce or be bound by these contracts unless specifically agreed otherwise.
54+
- Principals are bound by the acts of agents within their authority, and in some cases, even by unauthorized acts if they led third parties to believe these were within the agent's authority.
55+
- Misrepresentations or frauds by agents in their business affect the principal as if they had committed them, but not if these acts were outside the agent's authority.
56+
- The chapter on partnership has been repealed and replaced by the Indian Partnership Act, 1932.

0 commit comments

Comments
 (0)