Skip to content
Open
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
20 changes: 20 additions & 0 deletions src/assets/RegenerateIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from "react";
import { SVGProps } from "react";

const RegenerateIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
width="14"
height="auto"
fill="none"
{...props}
>
<path
d="M105.1 202.6c7.7-21.8 20.2-42.3 37.8-59.8c62.5-62.5 163.8-62.5 226.3 0L386.3 160H336c-17.7 0-32 14.3-32 32s14.3 32 32 32H463.5c0 0 0 0 0 0h.4c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32s-32 14.3-32 32v51.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0C73.2 122 55.6 150.7 44.8 181.4c-5.9 16.7 2.9 34.9 19.5 40.8s34.9-2.9 40.8-19.5zM39 289.3c-5 1.5-9.8 4.2-13.7 8.2c-4 4-6.7 8.8-8.1 14c-.3 1.2-.6 2.5-.8 3.8c-.3 1.7-.4 3.4-.4 5.1V448c0 17.7 14.3 32 32 32s32-14.3 32-32V396.9l17.6 17.5 0 0c87.5 87.4 229.3 87.4 316.7 0c24.4-24.4 42.1-53.1 52.9-83.7c5.9-16.7-2.9-34.9-19.5-40.8s-34.9 2.9-40.8 19.5c-7.7 21.8-20.2 42.3-37.8 59.8c-62.5 62.5-163.8 62.5-226.3 0l-.1-.1L125.6 352H176c17.7 0 32-14.3 32-32s-14.3-32-32-32H48.4c-1.6 0-3.2 .1-4.8 .3s-3.1 .5-4.6 1z"
fill="currentColor"
/>
</svg>
);

export default RegenerateIcon;
31 changes: 31 additions & 0 deletions src/components/chat/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type ChatProps = {
loading: boolean;
streamLoading: boolean;
stopGenerating: () => void;
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
};

const blippy = authorsConfig[0];
Expand All @@ -45,6 +46,7 @@ const ChatScreen = ({
loading,
streamLoading,
stopGenerating,
setMessages,
}: ChatProps) => {
const messageListRef = useRef<HTMLDivElement>(null);
const textAreaRef = useRef<HTMLTextAreaElement>(null);
Expand Down Expand Up @@ -127,6 +129,33 @@ const ChatScreen = ({
startChat(question, author.slug, { startChat: true });
};

const handleRegenerateResponse = (messageId: string) => {
// Find the index of the API message to regenerate
const apiMessageIndex = messages.findIndex(
(msg) => msg.uniqueId === messageId && msg.type === "apiMessage"
);

if (apiMessageIndex === -1) return;

// Find the previous user message
let userMessageIndex = apiMessageIndex - 1;
while (userMessageIndex >= 0 && messages[userMessageIndex].type !== "userMessage") {
userMessageIndex--;
}

if (userMessageIndex === -1) return;

const userMessage = messages[userMessageIndex].message;

// Remove the API message from messages array
setMessages((prevMessages) =>
prevMessages.filter((msg) => msg.uniqueId !== messageId)
);

// Regenerate the response
startChat(userMessage, author.slug, { startChat: true });
};

useEffect(() => {
const messageListBox = messageListRef.current;
if (!messageListBox) return;
Expand Down Expand Up @@ -288,6 +317,7 @@ const ChatScreen = ({
author={author.name}
content={message}
handleFollowUpQuestion={handleFollowUpQuestion}
handleRegenerateResponse={handleRegenerateResponse}
/>
{isApiMessage && (
<Rating
Expand All @@ -309,6 +339,7 @@ const ChatScreen = ({
loading={loading}
streamLoading={streamLoading}
handleFollowUpQuestion={handleFollowUpQuestion}
handleRegenerateResponse={handleRegenerateResponse}
/>
)}
</Box>
Expand Down
24 changes: 24 additions & 0 deletions src/components/message/markdownWrapper/markdownWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import atomDark from "react-syntax-highlighter/dist/cjs/styles/prism/atom-dark";
import styles from ".././message.module.css";
import Image from "next/image";
import CopyIcon from "@/assets/CopyIcon";
import RegenerateIcon from "@/assets/RegenerateIcon";
import { useState } from "react";
import rehypeInlineCodeProperty from "../../../utils/rehypeInlineCodeProperty";
import { useCopyToClipboard } from "usehooks-ts";
Expand Down Expand Up @@ -62,6 +63,29 @@ export const CopyResponseButton = ({
</Flex>
);
};

export const RegenerateButton = ({
onRegenerate,
isDisabled,
}: {
onRegenerate: () => void;
isDisabled?: boolean;
}) => {
return (
<Flex
onClick={isDisabled ? undefined : onRegenerate}
cursor={isDisabled ? "not-allowed" : "pointer"}
alignItems={"center"}
gap={1}
maxWidth={"max-content"}
opacity={isDisabled ? 0.5 : 1}
>
<Text>Regenerate</Text>
<RegenerateIcon />
</Flex>
);
};

const MarkdownWrapper = ({
text,
className,
Expand Down
29 changes: 24 additions & 5 deletions src/components/message/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { separateLinksFromApiMessage } from "@/utils/links";
import MarkdownWrapper, {
CopyButton,
CopyResponseButton,
RegenerateButton,
} from "./markdownWrapper/markdownWrapper";

type MessageType =
Expand Down Expand Up @@ -64,12 +65,14 @@ const MessageBox = ({
loading,
streamLoading,
handleFollowUpQuestion,
handleRegenerateResponse,
}: {
content: Message;
author: string;
loading?: boolean;
streamLoading?: boolean;
handleFollowUpQuestion: (question: string) => void;
handleRegenerateResponse?: (messageId: string) => void;
}) => {
const { message, type } = content;

Expand All @@ -96,15 +99,19 @@ const MessageBox = ({
<MessageContent
message={message}
type={type}
uniqueId={""}
uniqueId={content.uniqueId}
handleFollowUpQuestion={handleFollowUpQuestion}
handleRegenerateResponse={handleRegenerateResponse}
isLoading={streamLoading}
/>
) : (
<MessageContent
message={message}
type={type}
uniqueId={""}
uniqueId={content.uniqueId}
handleFollowUpQuestion={handleFollowUpQuestion}
handleRegenerateResponse={handleRegenerateResponse}
isLoading={loading || streamLoading}
/>
)}
</Flex>
Expand Down Expand Up @@ -166,8 +173,15 @@ const ClickableQuestions = ({
const MessageContent = ({
message,
type,
uniqueId,
handleFollowUpQuestion,
}: Message & { handleFollowUpQuestion: (question: string) => void }) => {
handleRegenerateResponse,
isLoading,
}: Message & {
handleFollowUpQuestion: (question: string) => void;
handleRegenerateResponse?: (messageId: string) => void;
isLoading?: boolean;
}) => {
if (!message?.trim()) return null;
const { messageBody, messageLinks, messageQuestions, isErrorMessage } =
separateLinksFromApiMessage(message);
Expand Down Expand Up @@ -225,9 +239,14 @@ const MessageContent = ({
)}

{showCopyIcon && (
<Flex paddingY={"16px"} gap={2} alignItems={"center"} maxH={"max-content"} marginTop={"16px"}>

<Flex paddingY={"16px"} gap={4} alignItems={"center"} maxH={"max-content"} marginTop={"16px"}>
<CopyResponseButton isCopyText msg={message} />
{handleRegenerateResponse && (
<RegenerateButton
onRegenerate={() => handleRegenerateResponse(uniqueId)}
isDisabled={isLoading}
/>
)}
</Flex>
)}
</>
Expand Down
1 change: 1 addition & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export default function Home() {
loading={loading}
streamLoading={streamLoading}
stopGenerating={abortGeneration}
setMessages={setMessages}
/>
) : (
<HomePage onPrompt={promptChat} />
Expand Down