From 789a89587625534aef7dbe4df9fb5f26f0c76659 Mon Sep 17 00:00:00 2001
From: Spyros
Date: Tue, 29 Aug 2023 17:46:06 +0100
Subject: [PATCH] Fix chatbot answers presentation (#345)
* remove versions from pillow and make psycopg install the binary version
* fix prompt client edge case bug
* lint
* fixed how the chatbot presents answers, tickets #331 and #342
* lint
* fix smartlink bug
* lint
---
.../frontend/src/pages/chatbot/chatbot.tsx | 31 ++++++++++++++++---
application/prompt_client/prompt_client.py | 9 +++---
application/tests/web_main_test.py | 11 +++----
application/web/web_main.py | 7 +++--
4 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/application/frontend/src/pages/chatbot/chatbot.tsx b/application/frontend/src/pages/chatbot/chatbot.tsx
index 8664de593..73eec06e7 100644
--- a/application/frontend/src/pages/chatbot/chatbot.tsx
+++ b/application/frontend/src/pages/chatbot/chatbot.tsx
@@ -299,11 +299,25 @@ export const Chatbot = () => {
}
function displayDocument(d: Document) {
+ var link = '/node/' + d.doctype.toLowerCase() + '/' + d.name;
+ if (d.section) {
+ link = link + '/section/' + d.section;
+ } else {
+ link = link + '/sectionid/' + d.sectionID;
+ }
return (
-
- *Reference: The above answer was based on the {d.name} section of{' '}
- {d.section ? d.section : d.sectionID};
-
+
+
+ *Reference: The above answer was based on:
+
+ {' '}
+ {d.name} section: {d.section ? d.section : d.sectionID};
+
+
+
+ You can find more information about {d.name} on its OpenCRE page
+
+
);
}
@@ -372,6 +386,15 @@ export const Chatbot = () => {
+
+
+ ChatCRE uses Google's PALM2 LLM, you can find the code for OpenCRE in
+ https://github.com/owaps/OpenCRE. Your question travels to Heroku (OpenCRE hosting provider)
+ and then to GCP over a protected connection. Your data is never stored in the OpenCRE
+ servers, you can start a new session by refreshing your page. The OpenCRE team has taken all
+ reasonable precautions we could think off to protect your privacy and security.
+
+
diff --git a/application/prompt_client/prompt_client.py b/application/prompt_client/prompt_client.py
index 95918bccc..280556b1d 100644
--- a/application/prompt_client/prompt_client.py
+++ b/application/prompt_client/prompt_client.py
@@ -415,9 +415,9 @@ def generate_text(self, prompt: str) -> Dict[str, str]:
timestamp = datetime.now().strftime("%I:%M:%S %p")
if not prompt:
return {"response": "", "table": "", "timestamp": timestamp}
- logger.info(f"getting embeddings for {prompt}")
+ logger.debug(f"getting embeddings for {prompt}")
question_embedding = self.ai_client.get_text_embeddings(prompt)
- logger.info(f"retrieved embeddings for {prompt}")
+ logger.debug(f"retrieved embeddings for {prompt}")
# Find the closest area in the existing embeddings
closest_id, similarity = self.get_id_of_most_similar_node_paginated(
@@ -426,8 +426,7 @@ def generate_text(self, prompt: str) -> Dict[str, str]:
)
closest_object = self.database.get_node_by_db_id(closest_id)
answer = ""
-
- logger.info(
+ logger.debug(
f"The prompt {prompt}, was most similar to object \n{closest_object}\n, with similarity:{similarity}"
)
closest_content = ""
@@ -449,7 +448,7 @@ def generate_text(self, prompt: str) -> Dict[str, str]:
else:
return {"response": "An adequate answer could not be found", "table": [""]}
- logger.info(f"retrieved completion for {prompt}")
+ logger.debug(f"retrieved completion for {prompt}")
table = [closest_object]
result = f"Answer: {answer}"
return {"response": result, "table": table}
diff --git a/application/tests/web_main_test.py b/application/tests/web_main_test.py
index b79807a3f..224328750 100644
--- a/application/tests/web_main_test.py
+++ b/application/tests/web_main_test.py
@@ -543,7 +543,7 @@ def test_smartlink(self) -> None:
for head in response.headers:
if head[0] == "Location":
location = head[1]
- self.assertEqual(location, "/node/Standard/CWE/sectionid/456")
+ self.assertEqual(location, "/node/standard/CWE/sectionid/456")
self.assertEqual(302, response.status_code)
response = client.get(
@@ -554,9 +554,10 @@ def test_smartlink(self) -> None:
for head in response.headers:
if head[0] == "Location":
location = head[1]
- self.assertEqual(location, "/node/Standard/ASVS/section/v0.1.2")
+ self.assertEqual(location, "/node/standard/ASVS/section/v0.1.2")
self.assertEqual(302, response.status_code)
+ # negative test, this cwe does not exist, therefore there is nowhere to redirect to
response = client.get(
"/smartlink/standard/CWE/999",
headers={"Content-Type": "application/json"},
@@ -565,7 +566,5 @@ def test_smartlink(self) -> None:
for head in response.headers:
if head[0] == "Location":
location = head[1]
- self.assertEqual(
- location, "https://cwe.mitre.org/data/definitions/999.html"
- )
- self.assertEqual(302, response.status_code)
+ self.assertEqual(location, "")
+ self.assertEqual(404, response.status_code)
diff --git a/application/web/web_main.py b/application/web/web_main.py
index 9381c8079..c7dcbf122 100644
--- a/application/web/web_main.py
+++ b/application/web/web_main.py
@@ -300,8 +300,9 @@ def smartlink(
opt_version = request.args.get("version")
# match ntype to the credoctypes case-insensitive
typ = [t for t in defs.Credoctypes if t.value.lower() == ntype.lower()]
+ doctype = None
if typ:
- ntype = typ[0]
+ doctype = typ[0]
page = 1
items_per_page = 1
@@ -312,7 +313,7 @@ def smartlink(
page=int(page),
items_per_page=int(items_per_page),
version=opt_version,
- ntype=ntype,
+ ntype=doctype,
)
if not nodes or len(nodes) == 0:
@@ -322,7 +323,7 @@ def smartlink(
page=int(page),
items_per_page=int(items_per_page),
version=opt_version,
- ntype=ntype,
+ ntype=doctype,
)
found_section_id = True
if nodes and len(nodes[0].links):