diff --git a/core/util/history.ts b/core/util/history.ts index 4a24c78d5..7a4fb62c3 100644 --- a/core/util/history.ts +++ b/core/util/history.ts @@ -102,7 +102,6 @@ class HistoryManager { if (sessionInfo.sessionId === session.sessionId) { sessionInfo.title = session.title; sessionInfo.workspaceDirectory = session.workspaceDirectory; - sessionInfo.dateCreated = String(Date.now()); found = true; break; } diff --git a/gui/src/hooks/useHistory.tsx b/gui/src/hooks/useHistory.tsx index 968146981..89bbda0ac 100644 --- a/gui/src/hooks/useHistory.tsx +++ b/gui/src/hooks/useHistory.tsx @@ -40,13 +40,16 @@ function useHistory(dispatch: Dispatch) { dispatch(newSession()); await new Promise((resolve) => setTimeout(resolve, 10)); - let title = truncateText( - stripImages(stateCopy.history[0].message.content) - .split("\n") - .filter((l) => l.trim() !== "") - .slice(-1)[0] || "", - 50, - ); + let title = + stateCopy.title === "New Session" + ? truncateText( + stripImages(stateCopy.history[0].message.content) + .split("\n") + .filter((l) => l.trim() !== "") + .slice(-1)[0] || "", + 50, + ) + : (await getSession(stateCopy.sessionId)).title; // to ensure titles are synced with updates from history page. if ( false && // Causing maxTokens to be set to 20 for main requests sometimes, so disabling until resolved diff --git a/gui/src/pages/history.tsx b/gui/src/pages/history.tsx index 6ad34e0e4..377455ec9 100644 --- a/gui/src/pages/history.tsx +++ b/gui/src/pages/history.tsx @@ -1,4 +1,8 @@ -import { ArrowLeftIcon, TrashIcon } from "@heroicons/react/24/outline"; +import { + ArrowLeftIcon, + PencilSquareIcon, + TrashIcon, +} from "@heroicons/react/24/outline"; import { SessionInfo } from "core"; import MiniSearch from "minisearch"; import React, { Fragment, useEffect, useState } from "react"; @@ -7,6 +11,7 @@ import { useNavigate } from "react-router-dom"; import styled from "styled-components"; import { defaultBorderRadius, + Input, lightGray, vscBackground, vscBadgeBackground, @@ -91,8 +96,28 @@ function TableRow({ const apiUrl = window.serverUrl; const workspacePaths = window.workspacePaths || [""]; const [hovered, setHovered] = useState(false); + const [editing, setEditing] = useState(false); + const [sessionTitleEditValue, setSessionTitleEditValue] = useState( + session.title, + ); - const { saveSession, deleteSession, loadSession } = useHistory(dispatch); + const { saveSession, deleteSession, loadSession, getSession, updateSession } = + useHistory(dispatch); + + const handleKeyUp = async (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + if (sessionTitleEditValue !== session.title) { + session.title = sessionTitleEditValue; + const persistedSessionInfo = await getSession(session.sessionId); + persistedSessionInfo.title = sessionTitleEditValue; + await updateSession(persistedSessionInfo); + setEditing(false); + } + } else if (e.key === "Escape") { + setEditing(false); + setSessionTitleEditValue(session.title); + } + }; return ( { // Save current session saveSession(); - await loadSession(session.sessionId); navigate("/"); }} > -
- {JSON.stringify(session.title).slice(1, -1)} +
+ {editing ? ( + titleInput && titleInput.focus()} + value={sessionTitleEditValue} + onChange={(e) => setSessionTitleEditValue(e.target.value)} + onKeyUp={(e) => handleKeyUp(e)} + onBlur={() => setEditing(false)} + /> + ) : ( + JSON.stringify(session.title).slice(1, -1) + )}
-
+ +
{date.toLocaleString("en-US", { year: "2-digit", month: "2-digit", @@ -122,10 +159,22 @@ function TableRow({ hour12: true, })} {" | "} - {lastPartOfPath(session.workspaceDirectory || "")}/ + {lastPartOfPath(session.workspaceDirectory || "")}
+ {hovered && ( + { + setEditing(true); + }} + > + + + )} + {hovered && (