无对话的新对话不进入历史会话
This commit is contained in:
@@ -0,0 +1,101 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { act, renderHook, waitFor } from "@testing-library/react";
|
||||||
|
|
||||||
|
import { useAgentChatSession } from "./useAgentChatSession";
|
||||||
|
|
||||||
|
jest.mock("@/lib/chatStream", () => ({
|
||||||
|
abortAgentChat: jest.fn(async () => undefined),
|
||||||
|
forkAgentChat: jest.fn(async () => "forked-session"),
|
||||||
|
streamAgentChat: jest.fn(async () => undefined),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const loadActiveChatState = jest.fn();
|
||||||
|
const listChatSessions = jest.fn();
|
||||||
|
|
||||||
|
jest.mock("../chatStorage", () => ({
|
||||||
|
deleteChatSession: jest.fn(async () => undefined),
|
||||||
|
listChatSessions: (...args: unknown[]) => listChatSessions(...args),
|
||||||
|
loadActiveChatState: (...args: unknown[]) => loadActiveChatState(...args),
|
||||||
|
loadChatSessionById: jest.fn(async () => ({
|
||||||
|
storageSessionId: "session-loaded",
|
||||||
|
title: "已存在会话",
|
||||||
|
isTitleManuallyEdited: false,
|
||||||
|
messages: [],
|
||||||
|
sessionId: undefined,
|
||||||
|
branchGroups: [],
|
||||||
|
})),
|
||||||
|
saveActiveChatState: jest.fn(async (state) => state.storageSessionId),
|
||||||
|
updateChatSessionTitle: jest.fn(async () => undefined),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("useAgentChatSession", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
loadActiveChatState.mockReset();
|
||||||
|
listChatSessions.mockReset();
|
||||||
|
|
||||||
|
loadActiveChatState.mockResolvedValue({
|
||||||
|
storageSessionId: undefined,
|
||||||
|
title: undefined,
|
||||||
|
isTitleManuallyEdited: false,
|
||||||
|
messages: [],
|
||||||
|
sessionId: undefined,
|
||||||
|
branchGroups: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not add a new empty session to history until there is actual chat content", async () => {
|
||||||
|
listChatSessions.mockResolvedValue([]);
|
||||||
|
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
useAgentChatSession({
|
||||||
|
onToolCall: jest.fn(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => expect(result.current.isHydrating).toBe(false));
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
void result.current.createSession();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => expect(result.current.sessionTitle).toBe("新对话"));
|
||||||
|
expect(result.current.chatSessions).toEqual([]);
|
||||||
|
expect(result.current.activeStorageSessionId).toBeUndefined();
|
||||||
|
expect(result.current.messages).toEqual([]);
|
||||||
|
expect(result.current.isStreaming).toBe(false);
|
||||||
|
expect(listChatSessions).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps existing history entries when creating a blank new session", async () => {
|
||||||
|
listChatSessions.mockResolvedValue([
|
||||||
|
{
|
||||||
|
id: "session-1",
|
||||||
|
title: "已有会话",
|
||||||
|
createdAt: 1,
|
||||||
|
updatedAt: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
useAgentChatSession({
|
||||||
|
onToolCall: jest.fn(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => expect(result.current.isHydrating).toBe(false));
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
void result.current.createSession();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.chatSessions).toEqual([
|
||||||
|
{
|
||||||
|
id: "session-1",
|
||||||
|
title: "已有会话",
|
||||||
|
createdAt: 1,
|
||||||
|
updatedAt: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -9,17 +9,14 @@ import type {
|
|||||||
BranchGroup,
|
BranchGroup,
|
||||||
BranchTransition,
|
BranchTransition,
|
||||||
ChatProgress,
|
ChatProgress,
|
||||||
ChatSessionSummary,
|
|
||||||
LoadedChatState,
|
LoadedChatState,
|
||||||
Message,
|
Message,
|
||||||
} from "../GlobalChatbox.types";
|
} from "../GlobalChatbox.types";
|
||||||
import {
|
import {
|
||||||
cloneBranchGroups,
|
cloneBranchGroups,
|
||||||
cloneMessages,
|
cloneMessages,
|
||||||
createId,
|
|
||||||
} from "../GlobalChatbox.utils";
|
} from "../GlobalChatbox.utils";
|
||||||
import {
|
import {
|
||||||
createEmptyChatSession,
|
|
||||||
deleteChatSession,
|
deleteChatSession,
|
||||||
listChatSessions,
|
listChatSessions,
|
||||||
loadActiveChatState,
|
loadActiveChatState,
|
||||||
@@ -550,21 +547,23 @@ export const useAgentChatSession = ({
|
|||||||
const controller = abortRef.current;
|
const controller = abortRef.current;
|
||||||
controller?.abort();
|
controller?.abort();
|
||||||
setBranchTransition(null);
|
setBranchTransition(null);
|
||||||
|
|
||||||
const newState = await createEmptyChatSession();
|
|
||||||
const sessions = await listChatSessions();
|
|
||||||
|
|
||||||
hydrationNonceRef.current += 1;
|
hydrationNonceRef.current += 1;
|
||||||
titleUpdateNonceRef.current += 1;
|
titleUpdateNonceRef.current += 1;
|
||||||
storageSessionIdRef.current = newState.storageSessionId;
|
storageSessionIdRef.current = undefined;
|
||||||
sessionIdRef.current = newState.sessionId;
|
sessionIdRef.current = undefined;
|
||||||
lastPersistedStateKeyRef.current = createPersistedStateKey(newState);
|
lastPersistedStateKeyRef.current = createPersistedStateKey({
|
||||||
setMessages(newState.messages);
|
storageSessionId: undefined,
|
||||||
setSessionTitle(newState.title);
|
title: "新对话",
|
||||||
setIsSessionTitleManuallyEdited(newState.isTitleManuallyEdited ?? false);
|
isTitleManuallyEdited: false,
|
||||||
setSessionId(newState.sessionId);
|
messages: [],
|
||||||
setBranchGroups(newState.branchGroups);
|
sessionId: undefined,
|
||||||
setChatSessions(sessions);
|
branchGroups: [],
|
||||||
|
});
|
||||||
|
setMessages([]);
|
||||||
|
setSessionTitle("新对话");
|
||||||
|
setIsSessionTitleManuallyEdited(false);
|
||||||
|
setSessionId(undefined);
|
||||||
|
setBranchGroups([]);
|
||||||
setIsStreaming(false);
|
setIsStreaming(false);
|
||||||
}, [isHydrating, isStreaming]);
|
}, [isHydrating, isStreaming]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user