Commit 244702c4 authored by edy's avatar edy

会话管理bug修复

parent d88fa0ca
......@@ -61,6 +61,31 @@ export function useChatSessionsController(deps: UseChatSessionsControllerDeps) {
setActiveProjectSession(preferredSessionId)
}, [activeSessionId, preferredSessionId, setActiveProjectSession])
useEffect(() => {
if (!workspace || !sessionScopeProjectId || workspace.currentProjectId !== sessionScopeProjectId) {
return
}
const scopedWorkspaceSessions = workspace.sessions.filter((session) => session.projectId === sessionScopeProjectId)
if (!scopedWorkspaceSessions.length) {
return
}
setSessions(scopedWorkspaceSessions)
if (sendPhase !== "idle" || scopedWorkspaceSessions.some((session) => session.id === activeSessionId)) {
return
}
setActiveProjectSession(scopedWorkspaceSessions[0].id)
}, [
activeSessionId,
sendPhase,
sessionScopeProjectId,
setActiveProjectSession,
setSessions,
workspace
])
useEffect(() => {
let cancelled = false
const preserveVisibleConversation = sendPhase !== "idle"
......@@ -151,19 +176,53 @@ export function useChatSessionsController(deps: UseChatSessionsControllerDeps) {
return
}
const preserveVisibleConversation = sendPhase !== "idle"
setProjectActionPending(true)
setErrorText("")
try {
const nextWorkspace = await desktopApi.projects.setActive(projectId)
setWorkspace(nextWorkspace)
clearSessions()
clearAllSessionMessages()
if (nextWorkspace.currentProjectId === projectId) {
const nextSessions = nextWorkspace.sessions.filter((session) => session.projectId === projectId)
if (nextSessions.length) {
setSessions(nextSessions)
const nextSessionId = resolvePreferredSessionId(nextSessions, activeSessionId)
if (nextSessionId) {
setActiveProjectSession(nextSessionId)
}
} else if (!preserveVisibleConversation) {
clearSessions()
clearAllSessionMessages()
setActiveProjectSession(EMPTY_SESSION_ID)
}
} else if (!preserveVisibleConversation) {
clearSessions()
clearAllSessionMessages()
setActiveProjectSession(EMPTY_SESSION_ID)
}
} catch (error) {
if (!preserveVisibleConversation) {
clearSessions()
clearAllSessionMessages()
setActiveProjectSession(EMPTY_SESSION_ID)
}
setErrorText(error instanceof Error ? error.message : String(error))
} finally {
setProjectActionPending(false)
}
}, [clearAllSessionMessages, clearSessions, desktopApi.projects, projectActionPending, setErrorText, setWorkspace])
}, [
activeSessionId,
clearAllSessionMessages,
clearSessions,
desktopApi.projects,
projectActionPending,
sendPhase,
setActiveProjectSession,
setErrorText,
setSessions,
setWorkspace
])
const switchProjectPreservingMessages = useCallback(async (projectId: string) => {
if (projectActionPending) {
......
......@@ -115,6 +115,7 @@ const finalState = result.finalState || {};
const finalWorkspace = finalState.workspaceSummary || {};
const expertEntry = sendResult.expertEntry || {};
const experts = finalState.experts || {};
const finalSessions = Array.isArray(finalState.sessions) ? finalState.sessions : [];
const standaloneIds = Array.isArray(experts.standaloneIds) ? experts.standaloneIds.map((value) => String(value || '')).sort() : [];
const homeShortcutIds = Array.isArray(experts.homeShortcutIds) ? experts.homeShortcutIds.map((value) => String(value || '')).sort() : [];
const standalonePromptAvailableIds = Array.isArray(experts.standalonePromptAvailableIds) ? experts.standalonePromptAvailableIds.map((value) => String(value || '')).sort() : [];
......@@ -157,6 +158,16 @@ if (expectedStandaloneIds.includes(expectedExpertEntryId)) {
if (String(finalWorkspace.currentProjectId || '') !== String(expertEntry.currentProjectId || '')) {
throw new Error('Standalone expert final project mismatch: ' + String(finalWorkspace.currentProjectId || ''));
}
if (String(finalState.ui && finalState.ui.sessionScopeProjectId || '') !== String(finalWorkspace.currentProjectId || '')) {
throw new Error('Standalone expert session scope mismatch: ' + String(finalState.ui && finalState.ui.sessionScopeProjectId || ''));
}
if (finalSessions.length < 1) {
throw new Error('Standalone expert did not expose any sessions for project: ' + String(finalWorkspace.currentProjectId || ''));
}
const foreignSession = finalSessions.find((session) => String(session && session.projectId || '') !== String(finalWorkspace.currentProjectId || ''));
if (foreignSession) {
throw new Error('Standalone expert exposed a session from another project: ' + JSON.stringify(foreignSession));
}
} else if (expectedHomeShortcutIds.includes(expectedExpertEntryId)) {
if (String(finalState.viewMode || '') !== 'chat') {
throw new Error('Home shortcut did not land on chat view.');
......@@ -190,6 +201,8 @@ console.log(JSON.stringify({
entryMode: expertEntry.entryMode || null,
finalViewMode: finalState.viewMode || null,
currentProjectId: finalWorkspace.currentProjectId || null,
sessionScopeProjectId: finalState.ui && finalState.ui.sessionScopeProjectId || null,
sessionCount: finalSessions.length,
standaloneIds,
homeShortcutIds,
standalonePromptAvailableIds
......
......@@ -461,6 +461,7 @@ if (smokeViewMode === 'skills') {
const finalWorkspace = finalState.workspaceSummary || {};
const experts = finalState.experts || {};
const expertEntry = sendResult.expertEntry || {};
const finalSessions = Array.isArray(finalState.sessions) ? finalState.sessions : [];
const standaloneIds = Array.isArray(experts.standaloneIds)
? experts.standaloneIds.map((value) => String(value || '')).sort()
: [];
......@@ -502,6 +503,16 @@ if (smokeViewMode === 'skills') {
if (!standalonePromptAvailableIds.includes(smokeExpertEntryId)) {
throw new Error('Standalone expert id did not report prompt availability: ' + smokeExpertEntryId);
}
if (String(finalState.ui && finalState.ui.sessionScopeProjectId || '') !== String(finalWorkspace.currentProjectId || '')) {
throw new Error('Standalone expert final session scope mismatch: ' + String(finalState.ui && finalState.ui.sessionScopeProjectId || ''));
}
if (finalSessions.length < 1) {
throw new Error('Standalone expert final state did not expose project sessions for: ' + String(finalWorkspace.currentProjectId || ''));
}
const foreignSession = finalSessions.find((session) => String(session && session.projectId || '') !== String(finalWorkspace.currentProjectId || ''));
if (foreignSession) {
throw new Error('Standalone expert final state exposed a session from another project: ' + JSON.stringify(foreignSession));
}
const streamSessionId = String(streamSmoke.sessionId || sendResult.sessionId || '');
if (streamSessionId && !streamSessionId.startsWith('project:' + String(expertEntry.currentProjectId || '') + ':')) {
throw new Error('Standalone expert entry did not send through the expected project session. session=' + streamSessionId + ' expected=' + String(expertEntry.currentProjectId || ''));
......@@ -821,4 +832,3 @@ finally {
Remove-Item Env:QJCLAW_SMOKE_STARTUP_ONLY -ErrorAction SilentlyContinue
Remove-Item Env:QJCLAW_SECRET_BACKEND -ErrorAction SilentlyContinue
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment