fix: stop chat hang after misrouted themed article requests

Route themed page/article prompts to agent orchestration, reject them
from portal direct chat, and finalize regular sessions to idle when a
direct chat turn already completed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-05 07:30:37 +08:00
parent a29158d589
commit 4781bbc156
5 changed files with 79 additions and 1 deletions
+38 -1
View File
@@ -82,6 +82,18 @@ function isDirectChatSessionId(sessionId?: string | null) {
return typeof sessionId === 'string' && sessionId.startsWith(DIRECT_CHAT_SESSION_PREFIX);
}
function sessionFinishedViaPortalDirectChat(messages: Message[], userMessage: Message) {
const lastAssistant = [...messages].reverse().find((message) => message.role === 'assistant');
if (lastAssistant?.metadata?.source !== 'portal-direct-chat') return false;
const userText = getDisplayText(userMessage).trim();
const userId = userMessage.id;
return messages.some(
(message) =>
message.role === 'user' &&
(message.id === userId || getDisplayText(message).trim() === userText),
);
}
async function waitForAgentRun(runId: string): Promise<AgentRun> {
return await waitForAgentRunWithDirectChatPreview(runId, {});
}
@@ -1344,8 +1356,33 @@ export function useTKMindChat(
activeRequestId.current = null;
setChatState('idle');
} else {
let finishedViaPortalDirectChat = false;
try {
const detail = await loadSessionDetail(activeSessionId);
if (submitToken === connectTokenRef.current) {
messagesRef.current = mergeConversationSnapshot(
messagesRef.current,
detail.messages,
);
messageHistoryLoadedCountRef.current = messagesRef.current.length;
setMessages(messagesRef.current);
setSession(detail.session);
finishedViaPortalDirectChat = sessionFinishedViaPortalDirectChat(
detail.messages,
userMessage,
);
}
} catch {
// Fall through to agent streaming when the snapshot is not ready yet.
}
subscribeToSession(activeSessionId);
setChatState('streaming');
if (finishedViaPortalDirectChat) {
clearActiveRequestMissingTimer();
activeRequestId.current = null;
setChatState('idle');
} else {
setChatState('streaming');
}
}
} catch (err) {
if (activeSessionId && isAmbiguousReplySubmitError(err)) {