无对话的新对话不进入历史会话
Build Push and Deploy / docker-image (push) Failing after 41s
Build Push and Deploy / deploy-fallback-log (push) Successful in 1s

This commit is contained in:
2026-05-20 15:33:43 +08:00
parent 98635e5247
commit 424555aae2
2 changed files with 116 additions and 16 deletions
@@ -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,
BranchTransition,
ChatProgress,
ChatSessionSummary,
LoadedChatState,
Message,
} from "../GlobalChatbox.types";
import {
cloneBranchGroups,
cloneMessages,
createId,
} from "../GlobalChatbox.utils";
import {
createEmptyChatSession,
deleteChatSession,
listChatSessions,
loadActiveChatState,
@@ -550,21 +547,23 @@ export const useAgentChatSession = ({
const controller = abortRef.current;
controller?.abort();
setBranchTransition(null);
const newState = await createEmptyChatSession();
const sessions = await listChatSessions();
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
storageSessionIdRef.current = newState.storageSessionId;
sessionIdRef.current = newState.sessionId;
lastPersistedStateKeyRef.current = createPersistedStateKey(newState);
setMessages(newState.messages);
setSessionTitle(newState.title);
setIsSessionTitleManuallyEdited(newState.isTitleManuallyEdited ?? false);
setSessionId(newState.sessionId);
setBranchGroups(newState.branchGroups);
setChatSessions(sessions);
storageSessionIdRef.current = undefined;
sessionIdRef.current = undefined;
lastPersistedStateKeyRef.current = createPersistedStateKey({
storageSessionId: undefined,
title: "新对话",
isTitleManuallyEdited: false,
messages: [],
sessionId: undefined,
branchGroups: [],
});
setMessages([]);
setSessionTitle("新对话");
setIsSessionTitleManuallyEdited(false);
setSessionId(undefined);
setBranchGroups([]);
setIsStreaming(false);
}, [isHydrating, isStreaming]);