Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show only message from error response #89

Merged
merged 3 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 89 additions & 81 deletions src/components/message/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import { USER_REFERENCE_NAME } from "@/config/ui-config";
import { separateLinksFromApiMessage } from "@/utils/links";
import MarkdownWrapper from "./markdownWrapper/markdownWrapper";

type MessageType = "userMessage" | "authorMessage" | "apiMessage" | "errorMessage" | "apiStream";
type MessageType =
| "userMessage"
| "authorMessage"
| "apiMessage"
| "errorMessage"
| "apiStream";
export interface Message {
message: string;
type: MessageType;
Expand Down Expand Up @@ -67,23 +72,37 @@ const MessageBox = ({

return (
<Flex
flexDir='column'
flexDir="column"
gap={{ base: 1, md: 2 }}
w='100%'
w="100%"
bgColor={messageConfig[type].bg ?? ""}
textAlign={type === "userMessage" ? "right" : "left"}
py={{ base: 3, md: 4 }}
px={{ base: 3, md: 4 }}
>
<Heading color={messageConfig[type].headingColor} fontSize='sm' fontWeight={600}>
<Heading
color={messageConfig[type].headingColor}
fontSize="sm"
fontWeight={600}
>
{type === "userMessage" ? USER_REFERENCE_NAME : author}
</Heading>
{loading ? (
<BeatLoader color='white' />
<BeatLoader color="white" />
) : streamLoading ? (
<StreamMessageContent message={message} type={type} uniqueId={""} handleFollowUpQuestion={handleFollowUpQuestion} />
<MessageContent
message={message}
type={type}
uniqueId={""}
handleFollowUpQuestion={handleFollowUpQuestion}
/>
) : (
<MessageContent message={message} type={type} uniqueId={""} handleFollowUpQuestion={handleFollowUpQuestion} />
<MessageContent
message={message}
type={type}
uniqueId={""}
handleFollowUpQuestion={handleFollowUpQuestion}
/>
)}
</Flex>
);
Expand All @@ -94,7 +113,12 @@ export default MessageBox;
const ClickableLink = ({ linkString }: { linkString: string }) => {
let url = linkString.split(" ")[1]?.trim();
return (
<a href={url} target='_blank' rel='noreferrer' className={styles.reference_link}>
<a
href={url}
target="_blank"
rel="noreferrer"
className={styles.reference_link}
>
{linkString}{" "}
<span style={{ marginLeft: "5px" }}>
<LinkShareIcon />
Expand All @@ -103,112 +127,96 @@ const ClickableLink = ({ linkString }: { linkString: string }) => {
);
};

const ClickableQuestions = ({ question, handleFollowUpQuestion }: { question: string; handleFollowUpQuestion: (question: string) => void }) => {
const ClickableQuestions = ({
question,
handleFollowUpQuestion,
}: {
question: string;
handleFollowUpQuestion: (question: string) => void;
}) => {
return (
<Button
minW='220px'
maxW='220px'
minH='120px'
h='100%'
w='100%'
padding='16px'
borderRadius='12px'
fontSize='14px'
fontWeight='400'
color='white'
bgGradient='linear(to-b, gray.900, brand.bg_base_purple)'
alignItems='flex-start'
textAlign='left'
dropShadow='dark-lg'
minW="220px"
maxW="220px"
minH="120px"
h="100%"
w="100%"
padding="16px"
borderRadius="12px"
fontSize="14px"
fontWeight="400"
color="white"
bgGradient="linear(to-b, gray.900, brand.bg_base_purple)"
alignItems="flex-start"
textAlign="left"
dropShadow="dark-lg"
_hover={{
scale: 1.5,
}}
onClick={() => handleFollowUpQuestion(question.trim())}
>
<Text whiteSpace='break-spaces'>{question}</Text>
<Text whiteSpace="break-spaces">{question}</Text>
</Button>
);
};

const MessageContent = ({ message, type, handleFollowUpQuestion }: Message & { handleFollowUpQuestion: (question: string) => void }) => {
const MessageContent = ({
message,
type,
handleFollowUpQuestion,
}: Message & { handleFollowUpQuestion: (question: string) => void }) => {
if (!message?.trim()) return null;
const { messageBody, messageLinks, messageQuestions } = separateLinksFromApiMessage(message);
const { messageBody, messageLinks, messageQuestions, isErrorMessage } =
separateLinksFromApiMessage(message);

if (!messageBody.trim()) return null;
if (!messageBody?.trim()) return null;

return (
<>
<Text whiteSpace='pre-wrap' color={messageConfig[type].color || ""}>
<Text whiteSpace="pre-wrap" color={messageConfig[type].color || ""}>
<MarkdownWrapper text={messageBody.trim()} />
</Text>
{Boolean(messageLinks.length) && (
{isErrorMessage ? null : (
<Box>
{Boolean(messageQuestions.length) && (
<Box paddingTop='16px'>
<Text fontSize='14px' paddingBottom='16px' fontWeight={500}>
<Box paddingTop="16px">
<Text fontSize="14px" paddingBottom="16px" fontWeight={500}>
Follow up questions
</Text>
<Flex alignItems='flex-start' justifyContent='flex-start' overflowX={messageQuestions?.length >= 2 ? `scroll` : "hidden"} gap='24px'>
<Flex
alignItems="flex-start"
justifyContent="flex-start"
overflowX={messageQuestions?.length >= 2 ? `scroll` : "hidden"}
gap="24px"
>
{messageQuestions.map((question, idx) => (
<ClickableQuestions
question={question}
key={`${question}_${idx}`}
handleFollowUpQuestion={() => handleFollowUpQuestion(question.trim())}
handleFollowUpQuestion={() => {
if (type === "apiMessage") {
handleFollowUpQuestion(question.trim());
}
}}
/>
))}
</Flex>
</Box>
)}
<Text fontSize='14px' paddingTop='16px' fontWeight={500}>
Sources
</Text>
{messageLinks.map((link, idx) => (
<div key={idx}>
<ClickableLink linkString={link} />
</div>
))}
{Boolean(messageLinks.length) && (
<>
<Text fontSize="14px" paddingTop="16px" fontWeight={500}>
Sources
</Text>
{messageLinks.map((link, idx) => (
<div key={idx}>
<ClickableLink linkString={link} />
</div>
))}
</>
)}
</Box>
)}
</>
);
};

const StreamMessageContent = ({ message, type, handleFollowUpQuestion }: Message & { handleFollowUpQuestion: (question: string) => void }) => {
const { messageBody, messageLinks, messageQuestions } = separateLinksFromApiMessage(message);

return (
<>
<Text whiteSpace='pre-wrap' color={messageConfig[type].color || ""}>
<MarkdownWrapper text={messageBody} className={`streamContent`} />
</Text>
<Box paddingTop='16px'>
{messageQuestions.length ? (
<Text fontSize='14px' paddingBottom='16px' fontWeight={500}>
Follow up questions
</Text>
) : null}
<Flex alignItems='flex-start' justifyContent='flex-start' overflowX='scroll' gap='24px'>
{messageQuestions.map((question, idx) => (
<ClickableQuestions
question={question}
key={`${question}_${idx}`}
handleFollowUpQuestion={() => handleFollowUpQuestion(question.trim())}
/>
))}
</Flex>
</Box>
<Box>
{messageLinks.length ? (
<Text fontSize='14px' fontWeight={500}>
Sources
</Text>
) : null}
{messageLinks.map((link, idx) => (
<div key={idx}>
<ClickableLink linkString={link} />
</div>
))}
</Box>
</>
);
};
2 changes: 1 addition & 1 deletion src/config/chatAPI-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ You are a helpful assistant. You are given a list of user questions, the questio
export const guidelines = {
BASE_INSTRUCTION:
"You are an AI assistant providing helpful answers. You are given the following extracted parts of a long document called CONTEXT BLOCK and a conversation. Provide a conversational detailed answer in the same writing style as based on the context provided. DO NOT include any external references or links in the answers.",
NO_ANSWER: `If you are absolutely certain that the answer cannot be found in the CONTEXT BLOCK, just say this phrase '${ERROR_MESSAGES.NO_ANSWER_WITH_LINKS}' EXACTLY. DO NOT try to make up an answer that is not in the CONTEXT BLOCK.`,
NO_ANSWER: `If you are absolutely certain that the answer cannot be found in the CONTEXT BLOCK, just say this phrase '${ERROR_MESSAGES.NO_ANSWER}' EXACTLY. DO NOT try to make up an answer that is not in the CONTEXT BLOCK.`,
UNRELATED_QUESTION: `If the question is not related to the context, say this phrase EXACTLY '${ERROR_MESSAGES.NO_ANSWER}'`,
LINKING: `DO NOT explicity mention the existence of the context provided, however, references can and should be made to the links provided in the context e.g '[0]'.`,
FOLLOW_UP_QUESTIONS: 'If you have an answer, generate four relevant follow up questions, do not include introductory text about follow-up questions. Each question must be in this format: `--{{ what problems did segwit solve }}--` in a new line.',
Expand Down
6 changes: 6 additions & 0 deletions src/utils/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { getAllErrorMessages } from "@/config/error-config";

export const messageIsErrorMessage = (message: string) => {
const errorMessages = getAllErrorMessages();
return errorMessages.includes(message.trim());
};
6 changes: 4 additions & 2 deletions src/utils/links.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { messageIsErrorMessage } from "./error";

const linksRegex = /(^\[\d+\]:\s.*)/gm;
const questionRegex = /--\{\{([^}]+)\}\}--/g;

Expand All @@ -10,9 +12,9 @@ export const separateLinksFromApiMessage = (message: string) => {
const body = body_and_questions_chunks[0]
const questions = body_and_questions_chunks.slice(1).map(question => question.trim()) ?? []

const messageBody = body;
const messageQuestions = questions;
const messageLinks = links;
const isErrorMessage = messageIsErrorMessage(body ?? "")

return { messageBody, messageLinks, messageQuestions };
return { messageBody: body, messageLinks, messageQuestions, isErrorMessage };
};
11 changes: 5 additions & 6 deletions src/utils/openaiChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const generateContextBlock = (summaries: SummaryData[]): string => {
let text = ""
try {
if (data === "[DONE]") {
text = getFinalAnswer("", link).data
text = formatLinksToSourcesList(link)
const queue = encoder.encode(text);
controller.enqueue(queue);
controller.close()
Expand Down Expand Up @@ -185,17 +185,16 @@ function removeDuplicatesByID(arr: CustomContent[]): CustomContent[] {
return filteredArr;
}

function getFinalAnswer(
summary: string,
function formatLinksToSourcesList(
content: SummaryData[]
) {
let data = summary.trim() + "\n\n";
let sourcesListString = "\n\n";

content.forEach((d: SummaryData, i: number) => {
data += `[${i}]: ${d.link}\n`;
sourcesListString += `[${i}]: ${d.link}\n`;
});

return { data };
return sourcesListString;
}

export async function processInput(
Expand Down