diff --git a/sweep_chat/components/App.tsx b/sweep_chat/components/App.tsx index 5357e68519..dda499c9b8 100644 --- a/sweep_chat/components/App.tsx +++ b/sweep_chat/components/App.tsx @@ -92,6 +92,7 @@ import { Message, CodeSuggestion, StatefulCodeSuggestion, + ChatSummary, } from '@/lib/types' import { Octokit } from 'octokit' @@ -113,6 +114,7 @@ import CodeMirrorMerge from 'react-codemirror-merge' import { dracula } from '@uiw/codemirror-theme-dracula' import { EditorView } from 'codemirror' import { debounce } from 'lodash' +import { formatDistanceToNow } from 'date-fns'; import { streamMessages } from '@/lib/streamingUtils' import { Alert, AlertDescription, AlertTitle } from './ui/alert' import { Skeleton } from './ui/skeleton' @@ -774,6 +776,11 @@ const parsePullRequests = async ( pull_number: parseInt(prNumber!), }) ).data.sort((a, b) => { + const aIsMarkdown = a.filename.endsWith('.md') || a.filename.endsWith('.rst') + const bIsMarkdown = b.filename.endsWith('.md') || b.filename.endsWith('.rst') + if (aIsMarkdown !== bIsMarkdown) { + return aIsMarkdown ? 1 : -1; + } const statusOrder: Record = { renamed: 0, copied: 1, @@ -864,6 +871,10 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { const [repos, setRepos] = useState([]) const [messagesId, setMessagesId] = useState(defaultMessageId) + const [previousChats, setPreviousChats] = useLocalStorage( + 'previousChats', + [] + ) const authorizedFetch = useCallback( (url: string, options: RequestInit = {}) => { @@ -881,11 +892,21 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { ) useEffect(() => { - console.log(defaultMessageId) - if (defaultMessageId) { + if (messagesId && !previousChats.some((chat) => chat.messagesId === messagesId) && messages.length > 0) { + setPreviousChats([...previousChats, { + messagesId: messagesId, + createdAt: new Date().toISOString(), + initialMessage: messages[0].content + }]) + } + }, [messagesId, messages.length]) + + useEffect(() => { + console.log('loading message', messagesId) + if (messagesId) { ;(async () => { const response = await authorizedFetch( - `/backend/messages/load/${defaultMessageId}`, + `/backend/messages/load/${messagesId}`, { method: 'GET', } @@ -936,7 +957,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { } })() } - }, [defaultMessageId]) + }, [messagesId]) useEffect(() => { if (messagesContainerRef.current) { @@ -1013,6 +1034,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { currentRepoName: string, currentMessages: Message[], currentSnippets: Snippet[], + currentMessagesId: string, currentUserMentionedPullRequest: PullRequest | null = null, currentUserMentionedPullRequests: PullRequest[] | null = null, currentCommitToPR: boolean = false, @@ -1035,7 +1057,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { repo_name: currentRepoName || repoName, messages: currentMessages || messages, snippets: currentSnippets || snippets, - message_id: messagesId || '', + message_id: currentMessagesId || '', original_code_suggestions: currentOriginalCodeSuggestions || originalSuggestedChanges, code_suggestions: currentSuggestedChanges || originalSuggestedChanges, @@ -1052,7 +1074,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { const saveData = await saveResponse.json() if (saveData.status == 'success') { const { message_id } = saveData - if (!messagesId && message_id) { + if (!currentMessagesId && message_id) { setMessagesId(message_id) const updatedUrl = `/c/${message_id}` window.history.pushState({}, '', updatedUrl) @@ -1068,6 +1090,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { repoName, messages, snippets, + currentMessagesId, userMentionedPullRequest, userMentionedPullRequests, commitToPR, @@ -1082,6 +1105,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { repoName, messages, snippets, + currentMessagesId, userMentionedPullRequest, userMentionedPullRequests, commitToPR, @@ -1099,12 +1123,12 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { ) // can tune these timeouts useEffect(() => { - console.log('pr', pullRequest) if (messages.length > 0 && snippets.length > 0) { debouncedSave( repoName, messages, snippets, + messagesId, userMentionedPullRequest, userMentionedPullRequests, commitToPR, @@ -1119,6 +1143,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { repoName, messages, snippets, + messagesId, userMentionedPullRequest, userMentionedPullRequests, commitToPR, @@ -1253,7 +1278,6 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { })) setSuggestedChanges(currentCodeSuggestions) } - console.log(isStream.current) if (!isStream.current) { currentCodeSuggestions = currentCodeSuggestions.map((suggestion) => suggestion.state == 'done' @@ -1265,7 +1289,6 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { state: 'error', } ) - console.log(currentCodeSuggestions) setSuggestedChanges(currentCodeSuggestions) } } catch (e: any) { @@ -1566,7 +1589,151 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { return ( <> -
+
+ +
+ { + window.location.href = '/' + }} + /> + + + +

+ Previous Chats +

+
+ + {previousChats.length > 0 ? previousChats.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, 10).map((chat) => ( + { + setMessagesId(chat.messagesId) + window.location.href = `/c/${chat.messagesId}` + }} + disabled={chat.messagesId === messagesId} + > + {truncate(chat.initialMessage, 80)} created {formatDistanceToNow(new Date(chat.createdAt), { addSuffix: true })} + + )) : ( + No history + )} + + {/* Warning: these message IDs are stored in local storage. + If you want to delete them, you will need to clear your browser cache. */} +
+ + + + + + + +

Settings

+ + + + + + + Anthropic + + + setModel(value as keyof typeof modelMap) + } + > + {Object.keys(modelMap).map((model) => + model.includes('claude') ? ( + + {modelMap[model]} + + ) : null + )} + + OpenAI + + + setModel(value as keyof typeof modelMap) + } + > + {Object.keys(modelMap).map((model) => + model.includes('gpt') ? ( + + {modelMap[model]} + + ) : null + )} + + + + +
+ {k} + setK(value[0])} + value={[k]} + className="w-[300px] my-0 py-0" + /> +
+
+
+ + + +
+ {session!.user!.name +
+
+ + +

+ {session!.user!.username! || session!.user!.name} +

+
+ {session?.user?.email && ( + {session.user.email} + )} + + setShowSurvey((prev) => !prev)} + > + + Feedback + + signOut()} + > + + Sign Out + +
+
+
+
+
{showSurvey && process.env.NEXT_PUBLIC_SURVEY_ID && ( - {/* */} ({ label: repo.full_name, @@ -1666,7 +1832,7 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { /> setBaseBranch(e.target.value)} /> @@ -1674,22 +1840,20 @@ function App({ defaultMessageId = '' }: { defaultMessageId?: string }) { - + {userMentionedPullRequest && commitToPR ? ( ) : ( - - -

Settings

- - - - - - - Anthropic - - - setModel(value as keyof typeof modelMap) - } - > - {Object.keys(modelMap).map((model) => - model.includes('claude') ? ( - - {modelMap[model]} - - ) : null - )} - - OpenAI - - - setModel(value as keyof typeof modelMap) - } - > - {Object.keys(modelMap).map((model) => - model.includes('gpt') ? ( - - {modelMap[model]} - - ) : null - )} - - - - -
- {k} - setK(value[0])} - value={[k]} - className="w-[300px] my-0 py-0" - /> -
-
- - - -
- {session!.user!.name -
-
- - -

- {session!.user!.username! || session!.user!.name} -

-
- {session?.user?.email && ( - {session.user.email} - )} - - setShowSurvey((prev) => !prev)} - > - - Feedback - - signOut()} - > - - Sign Out - -
-
{snippets.length && repoName ? (