Carry conversations into new sessions with a visible summary
- Bots get continue_in_new_session: the bot writes a title and summary, the session closes for good (read-only) and the new one opens with the summary as a "Carried over from the last session" message that links back to the old session. - Continue in new session (conversation menu, sessions modal) and the automatic rollover at the session length do the same; New session now starts a fresh, unlinked session. - Session length is an app setting in Settings > General. - ?session_id= opens a session; a carried-over one shows a bar linking to where the conversation went on instead of the composer. - The thread can open the previous session above the current one (shown only, never in the prompt), and replies get search_past_sessions and read_past_session. - Sessions are named from their opening messages, not their latest, and a carried summary is labelled as the earlier session's. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -15,7 +15,8 @@ type Params = {
|
||||
* Loads the open conversation's history once the page is on screen, and
|
||||
* again whenever the browser restores the page from its back-forward
|
||||
* cache (`pageshow` with `persisted`), so going back never shows an old
|
||||
* thread. Everything else on the page (the header, the composer) comes
|
||||
* thread. The page's `?session_id=` picks a session other than the
|
||||
* active one, read on every load. Everything else on the page (the header, the composer) comes
|
||||
* from the server and shows at once. `loaded` turns true with the first
|
||||
* load; a conversation the user can no longer open sends them where the
|
||||
* server says.
|
||||
@@ -37,7 +38,10 @@ export default function useConversationHistory({ bot_id, workspace_id, onLoaded
|
||||
setLoading(true);
|
||||
setError(undefined);
|
||||
|
||||
const res = await fetchConversationHistory({ bot_id, workspace_id }).catch(() => null);
|
||||
const session_id =
|
||||
Number(new URLSearchParams(window.location.search).get("session_id")) || null;
|
||||
|
||||
const res = await fetchConversationHistory({ bot_id, workspace_id, session_id }).catch(() => null);
|
||||
|
||||
/** A newer load started meanwhile: it has the last word. */
|
||||
if (id != request.current) return;
|
||||
|
||||
@@ -20,9 +20,12 @@ type Params = {
|
||||
|
||||
/**
|
||||
* Loads the session's older messages a page at a time, when the thread
|
||||
* is scrolled to its top. A session the thread moves onto starts with
|
||||
* its first message, so it has none older; `reset` starts over from a
|
||||
* loaded history instead.
|
||||
* is scrolled to its top. Once the session's first message is in, the
|
||||
* session it carries on from can be opened above it (`loadPrevious`, on
|
||||
* the user's ask) and paged the same way, and so on back. Those messages
|
||||
* are only shown: the bot's prompt still reads the session it answers in.
|
||||
* A session the thread moves onto starts with its first message, so it
|
||||
* has none older; `reset` starts over from a loaded history instead.
|
||||
*/
|
||||
export default function useOlderMessages({
|
||||
session_id,
|
||||
@@ -31,6 +34,11 @@ export default function useOlderMessages({
|
||||
onLoaded,
|
||||
}: Params) {
|
||||
const [has_more, setHasMore] = useState(initial_has_more);
|
||||
/**
|
||||
* The session the thread's top belongs to, and the one before it.
|
||||
*/
|
||||
const [paging_session_id, setPagingSessionId] = useState<number | null>(session_id || null);
|
||||
const [previous_session_id, setPreviousSessionId] = useState<number | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string>();
|
||||
const base_session = useRef(session_id);
|
||||
@@ -40,30 +48,41 @@ export default function useOlderMessages({
|
||||
|
||||
base_session.current = session_id;
|
||||
setHasMore(false);
|
||||
setPagingSessionId(session_id || null);
|
||||
setPreviousSessionId(null);
|
||||
setError(undefined);
|
||||
}, [session_id]);
|
||||
|
||||
/**
|
||||
* A history loaded for the session: whether it has older messages.
|
||||
* A history loaded for the session: whether it has older messages,
|
||||
* and the session it carries on from.
|
||||
*/
|
||||
const reset = useCallback(
|
||||
({ session_id, has_more }: { session_id: number; has_more: boolean }) => {
|
||||
({
|
||||
session_id,
|
||||
has_more,
|
||||
previous_session_id,
|
||||
}: {
|
||||
session_id: number;
|
||||
has_more: boolean;
|
||||
previous_session_id?: number | null;
|
||||
}) => {
|
||||
base_session.current = session_id;
|
||||
setHasMore(has_more);
|
||||
setPagingSessionId(session_id);
|
||||
setPreviousSessionId(previous_session_id || null);
|
||||
setError(undefined);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const loadOlder = async () => {
|
||||
if (loading || !has_more || !session_id || !first_message_id) return;
|
||||
|
||||
const load = async ({ session_id, before_id }: { session_id: number; before_id?: number | null }) => {
|
||||
setLoading(true);
|
||||
setError(undefined);
|
||||
|
||||
const res = await postSessionApi<OlderBotMessagesData>({
|
||||
path: "older-messages",
|
||||
body: { session_id, before_id: first_message_id },
|
||||
body: { session_id, before_id },
|
||||
}).catch(() => null);
|
||||
|
||||
setLoading(false);
|
||||
@@ -75,7 +94,29 @@ export default function useOlderMessages({
|
||||
|
||||
onLoaded({ messages: res.singleRes.messages });
|
||||
setHasMore(res.singleRes.has_more);
|
||||
setPagingSessionId(res.singleRes.session.id);
|
||||
setPreviousSessionId(res.singleRes.session.previous_session_id);
|
||||
};
|
||||
|
||||
return { has_more, loading, error, loadOlder, reset };
|
||||
const loadOlder = async () => {
|
||||
if (loading || !has_more || !paging_session_id || !first_message_id) return;
|
||||
|
||||
await load({ session_id: paging_session_id, before_id: first_message_id });
|
||||
};
|
||||
|
||||
const loadPrevious = async () => {
|
||||
if (loading || has_more || !previous_session_id) return;
|
||||
|
||||
await load({ session_id: previous_session_id });
|
||||
};
|
||||
|
||||
return {
|
||||
has_more,
|
||||
has_previous: !has_more && Boolean(previous_session_id),
|
||||
loading,
|
||||
error,
|
||||
loadOlder,
|
||||
loadPrevious,
|
||||
reset,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user