regenerate button (#138)
This commit is contained in:
		
							parent
							
								
									d7fdcd0dfe
								
							
						
					
					
						commit
						d27326125b
					
				|  | @ -4,7 +4,6 @@ import { ChatInput } from "./ChatInput"; | ||||||
| import { ChatLoader } from "./ChatLoader"; | import { ChatLoader } from "./ChatLoader"; | ||||||
| import { ChatMessage } from "./ChatMessage"; | import { ChatMessage } from "./ChatMessage"; | ||||||
| import { ModelSelect } from "./ModelSelect"; | import { ModelSelect } from "./ModelSelect"; | ||||||
| import { Regenerate } from "./Regenerate"; |  | ||||||
| import { SystemPrompt } from "./SystemPrompt"; | import { SystemPrompt } from "./SystemPrompt"; | ||||||
| 
 | 
 | ||||||
| interface Props { | interface Props { | ||||||
|  | @ -17,15 +16,13 @@ interface Props { | ||||||
|   messageError: boolean; |   messageError: boolean; | ||||||
|   loading: boolean; |   loading: boolean; | ||||||
|   lightMode: "light" | "dark"; |   lightMode: "light" | "dark"; | ||||||
|   onSend: (message: Message, isResend: boolean) => void; |   onSend: (message: Message, isResend?: boolean, deleteCount?: number) => void; | ||||||
|   onUpdateConversation: (conversation: Conversation, data: KeyValuePair) => void; |   onUpdateConversation: (conversation: Conversation, data: KeyValuePair) => void; | ||||||
|   onEditMessage: (message: Message, messageIndex: number) => void; |   onEditMessage: (message: Message, messageIndex: number) => void; | ||||||
|   onDeleteMessage: (message: Message, messageIndex: number) => void; |  | ||||||
|   onRegenerate: () => void; |  | ||||||
|   stopConversationRef: MutableRefObject<boolean>; |   stopConversationRef: MutableRefObject<boolean>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKeyIsSet, messageIsStreaming, modelError, messageError, loading, lightMode, onSend, onUpdateConversation, onEditMessage, onDeleteMessage, onRegenerate, stopConversationRef }) => { | export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKeyIsSet, messageIsStreaming, modelError, messageError, loading, lightMode, onSend, onUpdateConversation, onEditMessage, stopConversationRef }) => { | ||||||
|   const [currentMessage, setCurrentMessage] = useState<Message>(); |   const [currentMessage, setCurrentMessage] = useState<Message>(); | ||||||
|   const [autoScrollEnabled, setAutoScrollEnabled] = useState(true); |   const [autoScrollEnabled, setAutoScrollEnabled] = useState(true); | ||||||
| 
 | 
 | ||||||
|  | @ -55,6 +52,7 @@ export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKey | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     scrollToBottom(); |     scrollToBottom(); | ||||||
|     textareaRef.current?.focus(); |     textareaRef.current?.focus(); | ||||||
|  |     setCurrentMessage(conversation.messages[conversation.messages.length - 2]); | ||||||
|   }, [conversation.messages]); |   }, [conversation.messages]); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|  | @ -69,6 +67,8 @@ export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKey | ||||||
|     } |     } | ||||||
|   }, []); |   }, []); | ||||||
| 
 | 
 | ||||||
|  |   console.log("currentMessage", currentMessage); | ||||||
|  | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="relative flex-1 overflow-none dark:bg-[#343541] bg-white"> |     <div className="relative flex-1 overflow-none dark:bg-[#343541] bg-white"> | ||||||
|       {!(apiKey || serverSideApiKeyIsSet) ? ( |       {!(apiKey || serverSideApiKeyIsSet) ? ( | ||||||
|  | @ -120,7 +120,6 @@ export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKey | ||||||
|                     messageIndex={index} |                     messageIndex={index} | ||||||
|                     lightMode={lightMode} |                     lightMode={lightMode} | ||||||
|                     onEditMessage={onEditMessage} |                     onEditMessage={onEditMessage} | ||||||
|                     onDeleteMessage={onDeleteMessage} |  | ||||||
|                   /> |                   /> | ||||||
|                 ))} |                 ))} | ||||||
| 
 | 
 | ||||||
|  | @ -134,27 +133,22 @@ export const Chat: FC<Props> = ({ conversation, models, apiKey, serverSideApiKey | ||||||
|             )} |             )} | ||||||
|           </div> |           </div> | ||||||
| 
 | 
 | ||||||
|           {messageError ? ( |           <ChatInput | ||||||
|             <Regenerate |             stopConversationRef={stopConversationRef} | ||||||
|               onRegenerate={() => { |             textareaRef={textareaRef} | ||||||
|                 if (currentMessage) { |             messageIsStreaming={messageIsStreaming} | ||||||
|                   onSend(currentMessage, true); |             messages={conversation.messages} | ||||||
|                 } |             model={conversation.model} | ||||||
|               }} |             onSend={(message) => { | ||||||
|             /> |               setCurrentMessage(message); | ||||||
|           ) : ( |               onSend(message); | ||||||
|             <ChatInput |             }} | ||||||
|               stopConversationRef={stopConversationRef} |             onRegenerate={() => { | ||||||
|               textareaRef={textareaRef} |               if (currentMessage) { | ||||||
|               messageIsStreaming={messageIsStreaming} |                 onSend(currentMessage, true, 2); | ||||||
|               model={conversation.model} |               } | ||||||
|               onSend={(message) => { |             }} | ||||||
|                 setCurrentMessage(message); |           /> | ||||||
|                 onSend(message, false); |  | ||||||
|               }} |  | ||||||
|               onRegenerate={onRegenerate} |  | ||||||
|             /> |  | ||||||
|           )} |  | ||||||
|         </> |         </> | ||||||
|       )} |       )} | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|  | @ -1,17 +1,18 @@ | ||||||
| import { Message, OpenAIModel, OpenAIModelID } from "@/types"; | import { Message, OpenAIModel, OpenAIModelID } from "@/types"; | ||||||
| import { IconPlayerStop, IconSend } from "@tabler/icons-react"; | import { IconPlayerStop, IconRepeat, IconSend } from "@tabler/icons-react"; | ||||||
| import { FC, KeyboardEvent, MutableRefObject, useEffect, useState } from "react"; | import { FC, KeyboardEvent, MutableRefObject, useEffect, useState } from "react"; | ||||||
| 
 | 
 | ||||||
| interface Props { | interface Props { | ||||||
|   messageIsStreaming: boolean; |   messageIsStreaming: boolean; | ||||||
|   model: OpenAIModel; |   model: OpenAIModel; | ||||||
|  |   messages: Message[]; | ||||||
|   onSend: (message: Message) => void; |   onSend: (message: Message) => void; | ||||||
|   onRegenerate: () => void; |   onRegenerate: () => void; | ||||||
|   stopConversationRef: MutableRefObject<boolean>; |   stopConversationRef: MutableRefObject<boolean>; | ||||||
|   textareaRef: MutableRefObject<HTMLTextAreaElement | null>; |   textareaRef: MutableRefObject<HTMLTextAreaElement | null>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model, stopConversationRef, textareaRef }) => { | export const ChatInput: FC<Props> = ({ messageIsStreaming, model, messages, onSend, onRegenerate, stopConversationRef, textareaRef }) => { | ||||||
|   const [content, setContent] = useState<string>(); |   const [content, setContent] = useState<string>(); | ||||||
|   const [isTyping, setIsTyping] = useState<boolean>(false); |   const [isTyping, setIsTyping] = useState<boolean>(false); | ||||||
| 
 | 
 | ||||||
|  | @ -90,6 +91,20 @@ export const ChatInput: FC<Props> = ({ onSend, messageIsStreaming, model, stopCo | ||||||
|             Stop Generating |             Stop Generating | ||||||
|           </button> |           </button> | ||||||
|         )} |         )} | ||||||
|  | 
 | ||||||
|  |         {!messageIsStreaming && messages.length > 0 && ( | ||||||
|  |           <button | ||||||
|  |             className="absolute -top-2 md:top-0 left-0 right-0 mx-auto dark:bg-[#343541] border w-fit border-gray-500 py-2 px-4 rounded text-black dark:text-white hover:opacity-50" | ||||||
|  |             onClick={onRegenerate} | ||||||
|  |           > | ||||||
|  |             <IconRepeat | ||||||
|  |               size={16} | ||||||
|  |               className="inline-block mb-[2px]" | ||||||
|  |             />{" "} | ||||||
|  |             Regenerate response | ||||||
|  |           </button> | ||||||
|  |         )} | ||||||
|  | 
 | ||||||
|         <div className="flex flex-col w-full py-2 flex-grow md:py-3 md:pl-4 relative border border-black/10 bg-white dark:border-gray-900/50 dark:text-white dark:bg-[#40414F] rounded-md shadow-[0_0_10px_rgba(0,0,0,0.10)] dark:shadow-[0_0_15px_rgba(0,0,0,0.10)]"> |         <div className="flex flex-col w-full py-2 flex-grow md:py-3 md:pl-4 relative border border-black/10 bg-white dark:border-gray-900/50 dark:text-white dark:bg-[#40414F] rounded-md shadow-[0_0_10px_rgba(0,0,0,0.10)] dark:shadow-[0_0_15px_rgba(0,0,0,0.10)]"> | ||||||
|           <textarea |           <textarea | ||||||
|             ref={textareaRef} |             ref={textareaRef} | ||||||
|  |  | ||||||
|  | @ -10,10 +10,9 @@ interface Props { | ||||||
|   messageIndex: number; |   messageIndex: number; | ||||||
|   lightMode: "light" | "dark"; |   lightMode: "light" | "dark"; | ||||||
|   onEditMessage: (message: Message, messageIndex: number) => void; |   onEditMessage: (message: Message, messageIndex: number) => void; | ||||||
|   onDeleteMessage: (message: Message, messageIndex: number) => void; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const ChatMessage: FC<Props> = ({ message, messageIndex, lightMode, onEditMessage, onDeleteMessage }) => { | export const ChatMessage: FC<Props> = ({ message, messageIndex, lightMode, onEditMessage }) => { | ||||||
|   const [isEditing, setIsEditing] = useState<boolean>(false); |   const [isEditing, setIsEditing] = useState<boolean>(false); | ||||||
|   const [isHovering, setIsHovering] = useState<boolean>(false); |   const [isHovering, setIsHovering] = useState<boolean>(false); | ||||||
|   const [messageContent, setMessageContent] = useState(message.content); |   const [messageContent, setMessageContent] = useState(message.content); | ||||||
|  | @ -106,7 +105,7 @@ export const ChatMessage: FC<Props> = ({ message, messageIndex, lightMode, onEdi | ||||||
|               )} |               )} | ||||||
| 
 | 
 | ||||||
|               {(isHovering || window.innerWidth < 640) && !isEditing && ( |               {(isHovering || window.innerWidth < 640) && !isEditing && ( | ||||||
|                 <button className={`absolute ${window.innerWidth < 640 ? "right-1 bottom-1" : "right-[-20px] top-[26px]"}`}> |                 <button className={`absolute ${window.innerWidth < 640 ? "right-3 bottom-1" : "right-[-20px] top-[26px]"}`}> | ||||||
|                   <IconEdit |                   <IconEdit | ||||||
|                     size={20} |                     size={20} | ||||||
|                     className="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300" |                     className="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300" | ||||||
|  |  | ||||||
|  | @ -32,13 +32,15 @@ const Home: React.FC<HomeProps> = ({ serverSideApiKeyIsSet }) => { | ||||||
| 
 | 
 | ||||||
|   const stopConversationRef = useRef<boolean>(false); |   const stopConversationRef = useRef<boolean>(false); | ||||||
| 
 | 
 | ||||||
|   const handleSend = async (message: Message, isResend: boolean) => { |   const handleSend = async (message: Message, isResend = false, deleteCount = 0) => { | ||||||
|     if (selectedConversation) { |     if (selectedConversation) { | ||||||
|       let updatedConversation: Conversation; |       let updatedConversation: Conversation; | ||||||
| 
 | 
 | ||||||
|       if (isResend) { |       if (isResend) { | ||||||
|         const updatedMessages = [...selectedConversation.messages]; |         const updatedMessages = [...selectedConversation.messages]; | ||||||
|         updatedMessages.pop(); |         for (let i = 0; i < deleteCount; i++) { | ||||||
|  |           updatedMessages.pop(); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         updatedConversation = { |         updatedConversation = { | ||||||
|           ...selectedConversation, |           ...selectedConversation, | ||||||
|  | @ -373,13 +375,9 @@ const Home: React.FC<HomeProps> = ({ serverSideApiKeyIsSet }) => { | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleDeleteMessage = (message: Message, messageIndex: number) => {}; |  | ||||||
| 
 |  | ||||||
|   const handleRegenerate = () => {}; |  | ||||||
| 
 |  | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (currentMessage) { |     if (currentMessage) { | ||||||
|       handleSend(currentMessage, false); |       handleSend(currentMessage); | ||||||
|       setCurrentMessage(undefined); |       setCurrentMessage(undefined); | ||||||
|     } |     } | ||||||
|   }, [currentMessage]); |   }, [currentMessage]); | ||||||
|  | @ -524,8 +522,6 @@ const Home: React.FC<HomeProps> = ({ serverSideApiKeyIsSet }) => { | ||||||
|               onSend={handleSend} |               onSend={handleSend} | ||||||
|               onUpdateConversation={handleUpdateConversation} |               onUpdateConversation={handleUpdateConversation} | ||||||
|               onEditMessage={handleEditMessage} |               onEditMessage={handleEditMessage} | ||||||
|               onDeleteMessage={handleDeleteMessage} |  | ||||||
|               onRegenerate={handleRegenerate} |  | ||||||
|               stopConversationRef={stopConversationRef} |               stopConversationRef={stopConversationRef} | ||||||
|             /> |             /> | ||||||
|           </div> |           </div> | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ export const OpenAIStream = async (model: OpenAIModel, systemPrompt: string, key | ||||||
|         ...messages |         ...messages | ||||||
|       ], |       ], | ||||||
|       max_tokens: 1000, |       max_tokens: 1000, | ||||||
|       temperature: 0.0, |       temperature: 1, | ||||||
|       stream: true |       stream: true | ||||||
|     }) |     }) | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue