refactor: use backend chat sessions

This commit is contained in:
2026-06-04 15:02:27 +08:00
parent 20ca410e0a
commit e60e1f6453
9 changed files with 91 additions and 178 deletions
+24 -36
View File
@@ -9,15 +9,14 @@ import type {
} from "./GlobalChatbox.types";
import { cloneBranchGroups, cloneMessages } from "./GlobalChatbox.utils";
type RemoteSessionPayload = {
type BackendSessionPayload = {
id?: string;
title?: string;
created_at?: string | number;
updated_at?: string | number;
};
const emptyLoadedChatState = (): LoadedChatState => ({
storageSessionId: undefined,
export const createEmptyChatState = (): LoadedChatState => ({
title: undefined,
isTitleManuallyEdited: false,
messages: [],
@@ -58,7 +57,7 @@ const toMillis = (value: string | number | undefined) =>
const normalizeTitle = (value?: string) => value?.trim() || "新对话";
const fetchRemoteChatSessions = async (): Promise<ChatSessionSummary[]> => {
const fetchBackendChatSessions = async (): Promise<ChatSessionSummary[]> => {
const response = await apiFetch(`${config.AGENT_URL}/api/v1/agent/chat/sessions`, {
method: "GET",
projectHeaderMode: "include",
@@ -69,7 +68,7 @@ const fetchRemoteChatSessions = async (): Promise<ChatSessionSummary[]> => {
throw new Error(await response.text());
}
const payload = (await response.json()) as {
sessions?: RemoteSessionPayload[];
sessions?: BackendSessionPayload[];
};
return (payload.sessions ?? [])
.map((session) => ({
@@ -82,7 +81,7 @@ const fetchRemoteChatSessions = async (): Promise<ChatSessionSummary[]> => {
.sort(compareSessionsByAnchorTime);
};
const fetchRemoteChatSession = async (sessionId: string): Promise<LoadedChatState> => {
const fetchBackendChatSession = async (sessionId: string): Promise<LoadedChatState> => {
const response = await apiFetch(
`${config.AGENT_URL}/api/v1/agent/chat/session/${encodeURIComponent(sessionId)}`,
{
@@ -94,7 +93,7 @@ const fetchRemoteChatSession = async (sessionId: string): Promise<LoadedChatStat
);
if (!response.ok) {
if (response.status === 404) {
return emptyLoadedChatState();
return createEmptyChatState();
}
throw new Error(await response.text());
}
@@ -107,16 +106,15 @@ const fetchRemoteChatSession = async (sessionId: string): Promise<LoadedChatStat
branch_groups?: BranchGroup[];
};
return {
storageSessionId: payload.id,
title: normalizeTitle(payload.title),
isTitleManuallyEdited: payload.is_title_manually_edited ?? false,
messages: sanitizeMessages(payload.messages),
sessionId: payload.session_id,
sessionId: payload.session_id ?? payload.id,
branchGroups: sanitizeBranchGroups(payload.branch_groups),
};
};
const createRemoteChatSession = async (payload?: {
const createBackendChatSession = async (payload?: {
sessionId?: string;
parentSessionId?: string;
}) => {
@@ -146,7 +144,7 @@ const createRemoteChatSession = async (payload?: {
return sessionId;
};
const saveRemoteChatState = async (
const saveBackendChatState = async (
sessionId: string,
state: LoadedChatState,
): Promise<string> => {
@@ -175,7 +173,7 @@ const saveRemoteChatState = async (
return payload.id ?? payload.session_id ?? sessionId;
};
const updateRemoteChatSessionTitle = async (
const updateBackendChatSessionTitle = async (
sessionId: string,
title: string,
isTitleManuallyEdited?: boolean,
@@ -201,7 +199,7 @@ const updateRemoteChatSessionTitle = async (
}
};
const deleteRemoteChatSession = async (sessionId: string) => {
const deleteBackendChatSession = async (sessionId: string) => {
const response = await apiFetch(
`${config.AGENT_URL}/api/v1/agent/chat/session/${encodeURIComponent(sessionId)}`,
{
@@ -216,42 +214,34 @@ const deleteRemoteChatSession = async (sessionId: string) => {
}
};
export const loadActiveChatState = async (
_projectId?: string | null,
): Promise<LoadedChatState> => {
return emptyLoadedChatState();
};
export const saveActiveChatState = async (
state: LoadedChatState,
_projectId?: string | null,
): Promise<string | undefined> => {
if (typeof window === "undefined") return state.storageSessionId;
if (typeof window === "undefined") return state.sessionId;
if (!hasChatContent(state)) {
return undefined;
}
let remoteSessionId = state.sessionId ?? state.storageSessionId;
if (!remoteSessionId) {
remoteSessionId = await createRemoteChatSession();
let backendSessionId = state.sessionId;
if (!backendSessionId) {
backendSessionId = await createBackendChatSession();
}
const savedSessionId = await saveRemoteChatState(remoteSessionId, {
const savedSessionId = await saveBackendChatState(backendSessionId, {
...state,
storageSessionId: remoteSessionId,
sessionId: remoteSessionId,
sessionId: backendSessionId,
});
return savedSessionId;
};
export const listChatSessions = async (): Promise<ChatSessionSummary[]> => {
if (typeof window === "undefined") return [];
return await fetchRemoteChatSessions();
return await fetchBackendChatSessions();
};
export const updateChatSessionTitle = async (
storageSessionId: string,
sessionId: string,
title: string,
options?: {
isTitleManuallyEdited?: boolean;
@@ -261,8 +251,8 @@ export const updateChatSessionTitle = async (
const normalizedTitle = title.trim();
if (!normalizedTitle) return;
await updateRemoteChatSessionTitle(
storageSessionId,
await updateBackendChatSessionTitle(
sessionId,
normalizedTitle,
options?.isTitleManuallyEdited,
);
@@ -270,20 +260,18 @@ export const updateChatSessionTitle = async (
export const loadChatSessionById = async (
sessionId: string,
_projectId?: string | null,
): Promise<LoadedChatState> => {
if (typeof window === "undefined") return emptyLoadedChatState();
if (typeof window === "undefined") return createEmptyChatState();
return await fetchRemoteChatSession(sessionId);
return await fetchBackendChatSession(sessionId);
};
export const deleteChatSession = async (
sessionId: string,
_projectId?: string | null,
): Promise<string | undefined> => {
if (typeof window === "undefined") return undefined;
await deleteRemoteChatSession(sessionId);
await deleteBackendChatSession(sessionId);
const nextActiveSession = (await listChatSessions())[0];
return nextActiveSession?.id;
};