实现会话记录项目隔离
Build Push and Deploy / docker-image (push) Successful in 1m13s
Build Push and Deploy / deploy-fallback-log (push) Has been skipped

This commit is contained in:
2026-05-22 11:20:06 +08:00
parent 4bf99e8069
commit 54fbf15be8
5 changed files with 138 additions and 43 deletions
@@ -28,6 +28,7 @@ import {
} from "../chatStorage";
type UseAgentChatSessionOptions = {
projectId?: string | null;
onToolCall: (
event: StreamEvent & { type: "tool_call" },
options: {
@@ -145,6 +146,7 @@ const messagesEqual = (left: Message[], right: Message[]) =>
JSON.stringify(left) === JSON.stringify(right);
export const useAgentChatSession = ({
projectId,
onToolCall,
onBeforeSend,
getModel,
@@ -190,9 +192,37 @@ export const useAgentChatSession = ({
let cancelled = false;
const hydrate = async () => {
setIsHydrating(true);
hydrationCompletedRef.current = false;
if (!projectId) {
storageSessionIdRef.current = undefined;
sessionIdRef.current = undefined;
lastPersistedStateKeyRef.current = createPersistedStateKey({
storageSessionId: undefined,
title: undefined,
isTitleManuallyEdited: false,
messages: [],
sessionId: undefined,
branchGroups: [],
});
hydrationCompletedRef.current = true;
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
setBranchTransition(null);
setMessages([]);
setSessionTitle(undefined);
setIsSessionTitleManuallyEdited(false);
setSessionId(undefined);
setBranchGroups([]);
setChatSessions([]);
setIsHydrating(false);
return;
}
try {
const [loadedState, sessions] = await Promise.all([
loadActiveChatState(),
loadActiveChatState(projectId),
listChatSessions(),
]);
if (cancelled) return;
@@ -224,10 +254,10 @@ export const useAgentChatSession = ({
return () => {
cancelled = true;
};
}, []);
}, [projectId]);
useEffect(() => {
if (isHydrating || !hydrationCompletedRef.current) return;
if (!projectId || isHydrating || !hydrationCompletedRef.current) return;
const currentHydrationNonce = hydrationNonceRef.current;
const persistTimer = window.setTimeout(() => {
@@ -244,7 +274,7 @@ export const useAgentChatSession = ({
return;
}
void saveActiveChatState(state)
void saveActiveChatState(state, projectId)
.then((storageSessionId) => {
if (hydrationNonceRef.current !== currentHydrationNonce) return;
storageSessionIdRef.current = storageSessionId;
@@ -266,7 +296,7 @@ export const useAgentChatSession = ({
return () => {
window.clearTimeout(persistTimer);
};
}, [branchGroups, isHydrating, isSessionTitleManuallyEdited, messages, sessionId, sessionTitle]);
}, [branchGroups, isHydrating, isSessionTitleManuallyEdited, messages, projectId, sessionId, sessionTitle]);
useEffect(() => {
setBranchGroups((prev) => {
@@ -578,7 +608,7 @@ export const useAgentChatSession = ({
setIsHydrating(true);
try {
const [nextState, sessions] = await Promise.all([
loadChatSessionById(nextStorageSessionId),
loadChatSessionById(nextStorageSessionId, projectId),
listChatSessions(),
]);
@@ -600,7 +630,7 @@ export const useAgentChatSession = ({
setIsHydrating(false);
}
},
[isHydrating, isStreaming],
[isHydrating, isStreaming, projectId],
);
const removeSession = useCallback(
@@ -608,7 +638,10 @@ export const useAgentChatSession = ({
if (isHydrating || isStreaming) return;
try {
const nextActiveSessionId = await deleteChatSession(targetStorageSessionId);
const nextActiveSessionId = await deleteChatSession(
targetStorageSessionId,
projectId,
);
const sessions = await listChatSessions();
setChatSessions(sessions);
@@ -640,7 +673,7 @@ export const useAgentChatSession = ({
setIsHydrating(true);
const [nextState, sessionsAfterDelete] = await Promise.all([
loadChatSessionById(nextActiveSessionId),
loadChatSessionById(nextActiveSessionId, projectId),
listChatSessions(),
]);
hydrationNonceRef.current += 1;
@@ -661,7 +694,7 @@ export const useAgentChatSession = ({
setIsHydrating(false);
}
},
[isHydrating, isStreaming],
[isHydrating, isStreaming, projectId],
);
const sendPrompt = useCallback(