From a2d41f21df3792db90daec1f215715764172f2e0 Mon Sep 17 00:00:00 2001
From: Harry Li <harry.li@ll.mit.edu>
Date: Fri, 17 Jan 2025 16:24:08 -0500
Subject: [PATCH] added icons

---
 src/App.tsx                                   | 23 +++++++++++++--
 src/components/Chat/Chat.module.scss          |  4 ---
 src/components/Chat/Chat.tsx                  | 19 +++++++++++--
 src/components/IDTable/IDTable.tsx            |  9 +++++-
 src/components/InfoModal.tsx                  | 28 +++++++++++++++++++
 src/components/LLMWarning.tsx                 | 23 +++++++++++++++
 .../QueryEditor/QueryEditor.module.scss       |  9 ++++++
 src/components/QueryEditor/QueryEditor.tsx    | 15 ++++------
 8 files changed, 111 insertions(+), 19 deletions(-)
 create mode 100644 src/components/InfoModal.tsx
 create mode 100644 src/components/LLMWarning.tsx

diff --git a/src/App.tsx b/src/App.tsx
index 41ba1ae..02bee58 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -7,6 +7,8 @@ import { Chat } from 'components/Chat/Chat';
 import { DemoModeModal } from 'components/DemoModeModal';
 import { ErrorMessage } from 'components/ErrorMessage';
 import { IDTableContainer } from 'components/IDTable/IDTable';
+import { InfoModal } from 'components/InfoModal';
+import { LLMWarning } from 'components/LLMWarning';
 import { QueryEditor } from 'components/QueryEditor/QueryEditor'
 import { QueryVisualization } from "components/QueryVisualization/QueryVisualization";
 import { ResultsTable } from 'components/ResultsTable/ResultsTable';
@@ -67,9 +69,26 @@ function Results() {
     return (
       <>
         <Title order={4}>Results Summary from LLM</Title>
-        {results.summary ? <p>{results.summary}</p> : <ErrorMessage>There was an error generating a summary.</ErrorMessage>}
+        {results.summary ? (
+          <div>
+            <LLMWarning>
+              <p>This results summary was generated by an LLM that can make mistakes. Refer below to the Results Table from KG for ground-truth data.</p>
+              <p>Note that the absence of data does not necessairly mean that there is no data. It is possible that the query did not find what that you are looking for.</p>
+            </LLMWarning>
+
+            <p>{results.summary}</p>
+          </div>
+        ) : <ErrorMessage>There was an error generating a summary.</ErrorMessage>}
+        
         <hr/>
-        <Title order={4}>Results Table from KG</Title>
+        
+        <Title order={4}>
+          Results Table from KG
+          <InfoModal title="Results Table from KG">
+            <p>These are ground-truth results retrieved from the KG using the query you executed.</p>
+            <p>Note that the absence of data does not necessairly mean that there is no data. It is possible that the query did not find what that you are looking for.</p>
+          </InfoModal>
+        </Title>
         <ResultsTable data={results.data}/>
       </>
     )
diff --git a/src/components/Chat/Chat.module.scss b/src/components/Chat/Chat.module.scss
index 016d4ed..221b1ff 100644
--- a/src/components/Chat/Chat.module.scss
+++ b/src/components/Chat/Chat.module.scss
@@ -43,10 +43,6 @@
         padding: 0.5rem;
         margin-bottom: 0.5rem;
         border-radius: 5px;
-
-        button {
-          margin-top: 0.5rem;
-        }
       }
   
       &.user {
diff --git a/src/components/Chat/Chat.tsx b/src/components/Chat/Chat.tsx
index 905e54b..3d6e6cf 100644
--- a/src/components/Chat/Chat.tsx
+++ b/src/components/Chat/Chat.tsx
@@ -10,6 +10,7 @@ import { useMutation } from "@tanstack/react-query";
 import { IconCaretRight, IconSettings, IconZoomCode } from '@tabler/icons-react';
 
 import { ErrorMessage } from 'components/ErrorMessage';
+import { LLMWarning } from 'components/LLMWarning';
 
 import { useMakeChatGPTAPIInstance } from 'hooks/useMakeChatGPTAPIInstance';
 import { useRunQuery } from 'hooks/useRunQuery';
@@ -152,6 +153,10 @@ function RenderLLMResponse({
   if(parsedQuery) {
     return (
       <div className={styles.chat}>
+        <LLMWarning>
+          <p>This was generated by an LLM that can make mistakes.</p>
+        </LLMWarning>
+
         <RenderSparqlQuery
           pre={parsedQuery.pre}
           query={parsedQuery.query.trim()}
@@ -163,7 +168,15 @@ function RenderLLMResponse({
     )
   }
 
-  return <pre className={styles.chat}>{text}</pre>
+  return (
+    <div className={styles.chat}>
+      <LLMWarning>
+        <p>This was generated by an LLM that can make mistakes.</p>
+      </LLMWarning>
+      
+      <pre>{text}</pre>
+    </div>
+  )
 }
 
 
@@ -204,9 +217,9 @@ function RenderSparqlQuery({
       </div>
       <pre>{post}</pre>
       <br/>
-      <Button onClick={() => setInputText("You identified the wrong data. I was actually looking for: ")}>You identified the wrong data</Button>
+      <Button onClick={() => setInputText("You identified the wrong data. I was actually looking for: ")} style={{marginTop:"0.5rem"}}>You identified the wrong data</Button>
       <br/>
-      <Button onClick={() => setInputText("You misunderstood my question. I was actually asking about: ")}>You misunderstood my question</Button>
+      <Button onClick={() => setInputText("You misunderstood my question. I was actually asking about: ")} style={{marginTop:"0.5rem"}}>You misunderstood my question</Button>
       <br/>
       <Button onClick={() => setInputText("I want to ask something different: ")}>I want to ask something different</Button>
     </>
diff --git a/src/components/IDTable/IDTable.tsx b/src/components/IDTable/IDTable.tsx
index b29ffc2..405e598 100644
--- a/src/components/IDTable/IDTable.tsx
+++ b/src/components/IDTable/IDTable.tsx
@@ -4,6 +4,8 @@
 import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
 import { Table, Title } from "@mantine/core";
 
+import { InfoModal } from "components/InfoModal";
+
 import { useAppSelector } from "redux/store";
 
 import { IDTableEntitiesType } from "types/idTable";
@@ -38,7 +40,12 @@ export function IDTableContainer () {
 
     return (
         <div id={styles["id-table-container"]}>
-            <Title order={4}>Entity-Relation Table from KG</Title>
+            <Title order={4}>
+                Entity-Relation Table from KG
+                <InfoModal title="Entity-Relation Table from KG">
+                    <p>This table extracts the IDs from your query and explains what they mean in the KG.</p>
+                </InfoModal>
+            </Title>
             {content}
         </div>
     )
diff --git a/src/components/InfoModal.tsx b/src/components/InfoModal.tsx
new file mode 100644
index 0000000..5ec1baa
--- /dev/null
+++ b/src/components/InfoModal.tsx
@@ -0,0 +1,28 @@
+import { useDisclosure } from '@mantine/hooks';
+import { Modal, ActionIcon } from '@mantine/core';
+import { IconQuestionMark } from '@tabler/icons-react';
+
+export const InfoModal = ({
+  children,
+  title,
+}:{
+  children: React.ReactNode,
+  title: string,
+}) => {
+  const [opened, { open, close }] = useDisclosure(false);
+
+  return (
+    <>
+      <Modal opened={opened} onClose={close} title={title}>
+        {children}
+      </Modal>
+
+      <ActionIcon size="xs" variant="filled" aria-label={title} color="gray" onClick={open} style={{
+        marginLeft: "0.5em",
+        transform: "translateY(0.1em)",
+      }}>
+        <IconQuestionMark/>
+      </ActionIcon>
+    </>
+  );
+}
\ No newline at end of file
diff --git a/src/components/LLMWarning.tsx b/src/components/LLMWarning.tsx
new file mode 100644
index 0000000..e88357a
--- /dev/null
+++ b/src/components/LLMWarning.tsx
@@ -0,0 +1,23 @@
+import { useDisclosure } from '@mantine/hooks';
+import { Modal, ActionIcon } from '@mantine/core';
+import { IconAlertTriangle } from '@tabler/icons-react';
+
+export const LLMWarning = ({
+  children,
+}:{
+  children: React.ReactNode,
+}) => {
+  const [opened, { open, close }] = useDisclosure(false);
+
+  return (
+    <>
+      <Modal opened={opened} onClose={close} title="LLM Hallucination Warning">
+        {children}
+      </Modal>
+
+      <ActionIcon size="xs" variant="filled" aria-label="LLM Hallucination Warning" color="yellow" onClick={open} style={{float:"right"}}>
+        <IconAlertTriangle/>
+      </ActionIcon>
+    </>
+  );
+}
\ No newline at end of file
diff --git a/src/components/QueryEditor/QueryEditor.module.scss b/src/components/QueryEditor/QueryEditor.module.scss
index 1d85fc5..e18f120 100644
--- a/src/components/QueryEditor/QueryEditor.module.scss
+++ b/src/components/QueryEditor/QueryEditor.module.scss
@@ -6,4 +6,13 @@
   background-color: #fff;
   width: 100%;
   overflow-x: auto;
+}
+
+.query-history-button {
+  margin-top: 1em;
+
+  span {
+    white-space: wrap;
+    overflow: auto;
+  }
 }
\ No newline at end of file
diff --git a/src/components/QueryEditor/QueryEditor.tsx b/src/components/QueryEditor/QueryEditor.tsx
index 72d8bbc..4f10fe9 100644
--- a/src/components/QueryEditor/QueryEditor.tsx
+++ b/src/components/QueryEditor/QueryEditor.tsx
@@ -52,15 +52,12 @@ export function QueryEditor() {
               <Divider/>
               {queryHistory.map((record,i) => {
                 return (
-                  <div key={i}>
-                    <br/>
-                    <Button key={i} variant='default' onClick={() => {
-                      dispatch(setQueryValue(record.query))
-                      dispatch(setResults(record.results))
-                    }}>
-                      {i+1}: {record.name || "There was an error generating a name for this query"}
-                    </Button>
-                  </div>
+                  <Button key={i} className={styles["query-history-button"]} fullWidth variant='default' onClick={() => {
+                    dispatch(setQueryValue(record.query))
+                    dispatch(setResults(record.results))
+                  }}>
+                    {i+1}: {record.name || "There was an error generating a name for this query"}
+                  </Button>
                 )
               })}