Skip to content

Commit 52b7304

Browse files
authored
Merge pull request #549 from Lexpedite/llmify
Llmify
2 parents e2b7d58 + 30ccb9b commit 52b7304

File tree

10 files changed

+208
-5
lines changed

10 files changed

+208
-5
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ As of v0.2-alpha, this project is attempting to adhere to [Semantic Versioning](
77
While alpha, however, any version may include breaking changes that may not be specifically noted as such,
88
and breaking changes will not necessarily result in changes to the main version number.
99

10+
## [v1.6.15-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.15-alpha) 2023-05-23
11+
12+
### Added
13+
* If you provide an API access key for an OpenAI account, Blawx will use ChatGPT-3.5 to summarize its explanations and display those summaries in scenario editor.
14+
15+
### Changed
16+
* Disclaimer has been added to the GCWeb styled version of the scenario editor.
17+
18+
### TODO
19+
* Update the documentation for the scenario editor.
20+
1021
## [v1.6.14-alpha](https://github.com/Lexpedite/blawx/releases/tag/v1.6.14-alpha) 2023-05-12
1122

1223
### Added

INSTALL.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ cd blawx
2121
./update.sh
2222
```
2323

24+
Note that the `./update.sh` script runs the blawx server in the terminal, for development purposes, so that you can see debug information.
25+
If you want to run the docker container in the background, add `-d` as a flag to the `docker run` command in that script.
26+
2427
This command will take several minutes to run the first time.
2528

2629
The Blawx server will now be available at [http://127.0.0.1:8000](http://127.0.0.1:8000),
@@ -36,6 +39,16 @@ of running the `./update.sh` script.
3639
A demo account with username "demo" and password "blawx2022" is also created,
3740
and should be deleted in the admin interface if you want to restrict access to your server.
3841

42+
## Configure ChatGPT Integration
43+
44+
If you wish to run Blawx with ChatGPT integration, which allows for AI-generated summaries of explanations to be displayed
45+
to the user in the scenario editor, you will need to not use the `./update.sh` command, and instead enter these two commands:
46+
47+
```
48+
docker build -t blawx .
49+
docker run -it -p 8000:8000 -e OPENAI_API_KEY="your_key_goes_here" blawx
50+
```
51+
3952
## Updating Blawx
4053

4154
Blawx is under active development. Currently, updates are being sent to GitHub only, there is no published

blawx/fixtures/docs/components/scenario_editor.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@
110110
attributes, all those contingent answers will be included, also. You can see which answers are contingent
111111
by looking to see whether there are parts of the explanations that indicate the reason was assumed.
112112
113+
### ChatGPT-Generated Summaries
114+
115+
If you followed the instructions for providing Blawx with your OpenAI API Key, Scenario Editor will attempt
116+
to obtain AI-generated summaries of the details inside each explanation for an answer, and display that summary
117+
at the top of the explanation and provide the standard tree-structured explanation in a collapsable area beneath
118+
the summary. The summary will be prefaced with a warning that it was generated by a generative AI.
119+
113120
## View
114121
115122
The View tab of the scenario editor gives you the ability to customize the Facts tab by hiding various elements

blawx/fixtures/docs/features/answers.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@
108108
It is possible that age is a factor that can exclude you, but cannot include you. So you
109109
would not really be getting the answer to your question unless you ran both queries.
110110
111+
## ChatGPT Summaries of Explanations
112+
113+
If you provide Blawx with an OpenAI API Key when running the server (see `INSTALL.md` for details)
114+
in scenario editor your tree-structured explanations will be prefaced with an AI-generated plain-
115+
language summary. It is prefaced with a warning that it should not be relied upon for understanding
116+
how the reasoner reached the conclusion, and the actual tree-structured explanation on which it is
117+
based is still made available.
118+
111119
112120
113121

blawx/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ pyyaml
55
cobalt
66
clean-law >=0.0.4
77
django-guardian
8-
django-preferences
8+
django-preferences
9+
openai

blawx/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from pathlib import Path
1414

1515
# For adding a version identifier
16-
BLAWX_VERSION = "v1.6.14-alpha"
16+
BLAWX_VERSION = "v1.6.15-alpha"
1717

1818

1919
# Build paths inside the project like this: BASE_DIR / 'subdir'.

blawx/simplifier.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from django.http import Http404, HttpResponseNotFound, HttpResponseForbidden
2+
3+
from rest_framework.decorators import api_view, permission_classes, authentication_classes
4+
from rest_framework.response import Response
5+
# from rest_framework.permissions import AllowAny
6+
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
7+
from rest_framework.permissions import IsAuthenticated, DjangoObjectPermissions, IsAuthenticatedOrReadOnly, AllowAny
8+
9+
import openai
10+
import os
11+
12+
prompt_preamble = """
13+
What follows is an automatically generated explanation. Restate it in plain language without restating mathematical calculations and
14+
without further justifying conclusions for which there is only an absence of evidence in support.
15+
16+
17+
"""
18+
19+
@api_view(['POST'])
20+
@authentication_classes([SessionAuthentication])
21+
@permission_classes([IsAuthenticated])
22+
def simplify(request):
23+
if "OPENAI_API_KEY" in os.environ:
24+
completion = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt_preamble + request.data['explanation'] }])
25+
return Response(completion.choices[0].message.content)
26+
else:
27+
return Response("")

blawx/templates/blawx/scenario_editor.html

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1510,14 +1510,25 @@ <h6>Response</h6>
15101510
var model_count = j + 1;
15111511
var model_heading_name = "answer_" + count + "_model_" + model_count + "_heading";
15121512
var model_collapse_name = "answer_" + count + "_model_" + model_count + "_collapse";
1513+
1514+
15131515
output_content += '<div class="accordion-item"><h2 class="accordion-header" id="' + model_heading_name + '">';
15141516
output_content += '<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#' + model_collapse_name + '" aria-expanded="false" aria-controls="' + model_collapse_name + '">';
15151517
output_content += 'Explanation #' + model_count;
15161518
output_content += '</button></h2>';
15171519
output_content += '<div id="' + model_collapse_name + '" class="accordion-collapse collapse" aria-labelledby="' + model_heading_name + '" style="">';
1518-
//for (var attribute in models[j]['Residuals']) {
1520+
output_content += '<div id="' + model_collapse_name + '_simplified">';
1521+
output_content += '</div>';
1522+
//for (var attribute in models[j]['Residuals']) {
15191523
// attributes_output.push(describe_constraint(models[j]['Residuals'][attribute]));
15201524
//}
1525+
1526+
output_content += '<div id="' + model_collapse_name + '_detail_header" class="accordian-item"><h3 class="accordian-header">';
1527+
output_content += '<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#' + model_collapse_name + '_detail_content" aria-expanded="false" aria-controls="' + model_collapse_name + '_detail_content">';
1528+
output_content += 'Details';
1529+
output_content += '</button></h3>';
1530+
output_content += '<div id="' + model_collapse_name + '_detail_content" class="accordian-collapse collapse aria-labelledby="' + model_collapse_name + '_detail_header">';
1531+
15211532
var constraints_output = describe_constraints_new(models[j].Residuals, models[j].Terms);
15221533

15231534

@@ -1561,13 +1572,55 @@ <h6>Response</h6>
15611572
//output_content += getNodesFromModel(models[j].Raw);
15621573
// output_content += convertModelToParagraphs(models[j].Raw);
15631574
output_content += '</div></div>';
1575+
output_content += '</div></div>';
15641576

15651577
}
15661578
output_content += '</div></div></div>';
15671579
}
15681580
output_content += '</div>';
15691581
answer_element.innerHTML = output_content;
15701582

1583+
// Now we summarize them
1584+
for (var a = 0; a < parsed_test_response['Answers'].length; a++) {
1585+
for (var e = 0; e < parsed_test_response['Answers'][a]['Models'].length; e++) {
1586+
var target_explanation = document.getElementById("answer_" + (a+1) + "_model_" + (e+1) + "_collapse");
1587+
var target_summary = document.getElementById("answer_" + (a+1) + "_model_" + (e+1) + "_collapse_simplified");
1588+
var detail_header_name = "answer_" + (a+1) + "_model_" + (e+1) + "_collapse_detail_header";
1589+
var detail_content_name = "answer_" + (a+1) + "_model_" + (e+1) + "_collapse_detail_content";
1590+
var text_explanation = get_text_of_explanation(target_explanation);
1591+
var simplify_request = new XMLHttpRequest();
1592+
var warning_text = '<div class="alert alert-warning d-flex align-items-center alert-dismissible fade show" role="alert" id="answer_"' + (a+1) + "_model_" + (e+1) + '_collapse_simplified_warning">';
1593+
warning_text += '<i class="bi bi-exclamation-triangle-fill" aria-label="Warning:"></i>';
1594+
warning_text += '<div>The following summarization was automatically generated, and may not be accurate. The details below show the actual reasoning.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>'
1595+
warning_text += '</div>';
1596+
simplify_request.onload = function () {
1597+
if (this.responseText != '""') {
1598+
target_summary.innerHTML = warning_text + "Summary: " + this.responseText;
1599+
} else {
1600+
// There was no answer, so there is no summary. The contents of the details should be moved to the explanation part,
1601+
// and the details parts removed.
1602+
1603+
var detail_header_target = document.getElementById(detail_header_name);
1604+
var detail_content_target = document.getElementById(detail_content_name);
1605+
1606+
// Get the details content innerHTML
1607+
var explanation = detail_content_target.innerHTML;
1608+
// Set it to the value of the target.
1609+
target_summary.innerHTML = explanation;
1610+
// remove the header and the content elements.
1611+
detail_header_target.remove();
1612+
detail_content_target.remove();
1613+
}
1614+
}
1615+
simplify_request.open("POST", "{% url 'simplify' %}");
1616+
simplify_request.setRequestHeader("Content-Type", "application/json");
1617+
target_summary.innerHTML = "Getting AI Summary...";
1618+
console.log("Sending simplify request");
1619+
simplify_request.setRequestHeader('X-CSRFToken', csrftoken);
1620+
simplify_request.send(JSON.stringify({"explanation": text_explanation}));
1621+
}
1622+
}
1623+
15711624
$('#nav-answers-tab').tab('show');
15721625
draw_facts(); // So that new relevance information will be displayed in the interface.
15731626
} else {
@@ -1588,6 +1641,19 @@ <h6>Response</h6>
15881641
testrun_request.setRequestHeader('X-CSRFToken', csrftoken);
15891642
testrun_request.send(JSON.stringify(new_fact_data));
15901643
}
1644+
1645+
function get_text_of_explanation(element) {
1646+
var output = ""
1647+
if (element.hasChildNodes()) {
1648+
for (var c = 0; c < element.childNodes.length; c++) {
1649+
output += get_text_of_explanation(element.childNodes[c])
1650+
}
1651+
} else {
1652+
output += "\n" + element.data
1653+
}
1654+
return output;
1655+
}
1656+
15911657
var view_form_element = document.getElementById('viewform');
15921658
function toggle_view_hidden(input) {
15931659
index = hidden_by_view.indexOf(input);

0 commit comments

Comments
 (0)