fix(web): restore sessions from conversation detail authority
This commit is contained in:
@@ -153,29 +153,23 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
workspace.value = optimisticWorkspaceSelection(current, conversation, tabProjectId);
|
||||
void refreshSessionStatusById(sessionIdFromConversation(conversation));
|
||||
loading.value = true;
|
||||
const [response, detailResponse] = await Promise.all([
|
||||
api.workbench.selectConversation(current.workspaceId, { projectId: tabProjectId, conversationId: conversation.conversationId, sessionId: conversation.sessionId, threadId: conversation.threadId, updatedByClient: "cloud-web-vue" }),
|
||||
api.workbench.conversation(conversation.conversationId, { projectId: tabProjectId })
|
||||
]);
|
||||
const persistPromise = api.workbench.selectConversation(current.workspaceId, { projectId: tabProjectId, conversationId: conversation.conversationId, sessionId: conversation.sessionId, threadId: conversation.threadId, updatedByClient: "cloud-web-vue" });
|
||||
const detailResponse = await api.workbench.conversation(conversation.conversationId, { projectId: tabProjectId });
|
||||
const response = await persistPromise;
|
||||
loading.value = false;
|
||||
clearSwitchingConversation(conversation.conversationId);
|
||||
if (!isCurrentWorkspaceSelection(requestEpoch, conversation.conversationId)) return;
|
||||
if (response.ok) {
|
||||
const selectedConversation = detailResponse.ok ? detailResponse.data?.conversation ?? null : null;
|
||||
if (!selectedConversation) error.value = detailResponse.error ?? "conversation unavailable";
|
||||
const selectedProjectId = conversationProjectId(selectedConversation ?? conversation, tabProjectId);
|
||||
workspace.value = workspaceWithSelectedConversation(response.data?.workspace ?? current, selectedConversation ?? conversation, selectedProjectId);
|
||||
messages.value = restoreMessagesTraceAuthority(messagesFromSelectedConversation(selectedConversation, conversation.conversationId, null, []), messages.value);
|
||||
if (selectedConversation) conversations.value = mergeConversationIntoList(conversations.value, selectedConversation);
|
||||
void hydrateTurnStatusAuthority(messages.value);
|
||||
void hydrateTerminalMessageDiagnostics();
|
||||
void hydrateTraceEvents(messages.value);
|
||||
reattachRestoredActiveTrace();
|
||||
currentRequest.value = null;
|
||||
await refreshSelectedSessionStatus(selectedConversation ?? conversation);
|
||||
const selectedConversation = detailResponse.ok ? detailResponse.data?.conversation ?? null : null;
|
||||
if (selectedConversation) {
|
||||
const selectedProjectId = conversationProjectId(selectedConversation, tabProjectId);
|
||||
applySelectedConversationDetail(selectedConversation, response.ok ? response.data?.workspace ?? current : workspace.value ?? current, selectedProjectId, null, messages.value);
|
||||
error.value = null;
|
||||
void persistSelectedConversation(selectedConversation, selectedProjectId, response);
|
||||
await refreshSelectedSessionStatus(selectedConversation);
|
||||
await refreshConversations(conversation.conversationId);
|
||||
return;
|
||||
}
|
||||
error.value = detailResponse.error ?? "conversation unavailable";
|
||||
if (response.status === 404 && await retrySelectConversationWithFreshWorkspace(conversation, tabProjectId, requestEpoch)) return;
|
||||
error.value = response.error ?? "session switch failed";
|
||||
}
|
||||
@@ -203,9 +197,14 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
error.value = response.error ?? "session URL not found";
|
||||
return false;
|
||||
}
|
||||
const selectedProjectId = conversationProjectId(conversation, activeProjectId.value);
|
||||
applySelectedConversationDetail(conversation, current, selectedProjectId, null, messages.value);
|
||||
clearSwitchingConversation(normalized);
|
||||
error.value = null;
|
||||
void refreshSessionStatusById(sessionIdFromConversation(conversation));
|
||||
await selectConversation(conversation);
|
||||
return activeConversationId.value === normalized;
|
||||
void persistSelectedConversation(conversation, selectedProjectId);
|
||||
void refreshConversations(normalized);
|
||||
return activeConversationId.value === normalized && messages.value.length > 0;
|
||||
}
|
||||
|
||||
async function deleteCurrentSession(): Promise<void> {
|
||||
@@ -685,6 +684,37 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
if (switchingConversationId.value === conversationId) switchingConversationId.value = null;
|
||||
}
|
||||
|
||||
function applySelectedConversationDetail(conversation: ConversationRecord, baseWorkspace: WorkspaceRecord | null, selectedProjectId: string, previousConversationId: string | null, previousMessages: ChatMessage[]): void {
|
||||
workspace.value = workspaceWithSelectedConversation(baseWorkspace, conversation, selectedProjectId);
|
||||
messages.value = restoreMessagesTraceAuthority(messagesFromSelectedConversation(conversation, conversation.conversationId, previousConversationId, previousMessages), previousMessages);
|
||||
conversations.value = mergeConversationIntoList(conversations.value, conversation);
|
||||
conversationsReady.value = true;
|
||||
currentRequest.value = null;
|
||||
void hydrateTurnStatusAuthority(messages.value);
|
||||
void hydrateTerminalMessageDiagnostics();
|
||||
void hydrateTraceEvents(messages.value);
|
||||
reattachRestoredActiveTrace();
|
||||
}
|
||||
|
||||
async function persistSelectedConversation(conversation: ConversationRecord, selectedProjectId: string, existingResponse?: ApiResult<{ workspace?: WorkspaceRecord }>): Promise<void> {
|
||||
const conversationId = conversation.conversationId;
|
||||
let response = existingResponse ?? null;
|
||||
if (!response) {
|
||||
const workspaceId = workspace.value?.workspaceId;
|
||||
if (!workspaceId) return;
|
||||
response = await api.workbench.selectConversation(workspaceId, { projectId: selectedProjectId, conversationId, sessionId: conversation.sessionId, threadId: conversation.threadId, updatedByClient: "cloud-web-vue" });
|
||||
}
|
||||
if (!response.ok && response.status === 404) {
|
||||
const fresh = await api.workbench.workspace(selectedProjectId);
|
||||
const freshWorkspace = fresh.data?.workspace;
|
||||
if (fresh.ok && freshWorkspace?.workspaceId && activeConversationId.value === conversationId) {
|
||||
response = await api.workbench.selectConversation(freshWorkspace.workspaceId, { projectId: selectedProjectId, conversationId, sessionId: conversation.sessionId, threadId: conversation.threadId, updatedByClient: "cloud-web-vue-retry" });
|
||||
}
|
||||
}
|
||||
if (!response.ok || !response.data?.workspace || activeConversationId.value !== conversationId) return;
|
||||
workspace.value = workspaceWithSelectedConversation(response.data.workspace, conversation, selectedProjectId);
|
||||
}
|
||||
|
||||
async function retrySelectConversationWithFreshWorkspace(conversation: ConversationRecord, tabProjectId: string, requestEpoch: number): Promise<boolean> {
|
||||
const fresh = await api.workbench.workspace(tabProjectId);
|
||||
if (!isCurrentWorkspaceSelection(requestEpoch, conversation.conversationId)) return true;
|
||||
|
||||
Reference in New Issue
Block a user