feat: refine codex live chat context flows

This commit is contained in:
2026-05-08 21:15:51 +09:00
parent 82c0d8a197
commit 442879313f
92 changed files with 14815 additions and 7314 deletions

View File

@@ -47,6 +47,7 @@ export function ConversationRoomPane({
showScrollToBottom={false}
copiedMessageId={null}
draft=""
draftVersion={0}
composerAttachments={[]}
requestStateMap={requestStateMap}
isConversationLoading={isLoading}
@@ -85,6 +86,7 @@ export function ConversationRoomPane({
onCancelMessage={() => {}}
onDeleteRequest={() => {}}
onRemoveQueuedRequest={() => {}}
onSubmitPrompt={async () => false}
/>
);
}

View File

@@ -1,4 +1,5 @@
import {
clearChatConversationRoom,
createChatConversationRoom,
deleteChatConversationRequest,
deleteChatConversationRoom,
@@ -57,6 +58,7 @@ export type ChatGateway = {
>
>,
) => Promise<ChatConversationSummary>;
clearConversation: (sessionId: string) => Promise<ChatConversationSummary>;
deleteConversation: (sessionId: string) => Promise<void>;
deleteConversationRequest: (sessionId: string, requestId: string) => Promise<void>;
markConversationRead: (sessionId: string) => Promise<void>;
@@ -73,6 +75,7 @@ export const chatGateway: ChatGateway = {
createConversation: createChatConversationRoom,
renameConversation: renameChatConversationRoom,
updateConversation: updateChatConversationRoom,
clearConversation: clearChatConversationRoom,
deleteConversation: async (sessionId) => {
await deleteChatConversationRoom(sessionId);
},

View File

@@ -56,7 +56,7 @@ type UseConversationComposerControllerOptions = {
maxContextMessages: number;
maxContextChars: number;
};
draft: string;
getDraft: () => string;
composerAttachments: ChatComposerAttachment[];
isComposerAttachmentUploading: boolean;
selectedChatType: SelectedChatType;
@@ -74,7 +74,17 @@ type UseConversationComposerControllerOptions = {
setShowScrollToBottom: (value: boolean) => void;
setPendingContextConfirm: (value: PendingContextConfirm | null) => void;
upsertRequestItem: (request: ChatConversationRequest) => void;
syncConversationPreviewForRequest: (sessionId: string, text: string, requestedAt?: string) => void;
syncConversationPreviewForRequest: (
sessionId: string,
text: string,
requestedAt?: string,
options?: {
requestId?: string;
mode?: 'queue' | 'direct';
queueSize?: number;
jobMessage?: string | null;
},
) => void;
updatePendingMessageStatus: (requestId: string, status: 'retrying' | 'failed' | null, retryCount?: number) => void;
createLocalMessage: (text: string) => ChatMessage;
createChatMessage: (author: 'user' | 'codex' | 'system', text: string, requestId?: string | null) => ChatMessage;
@@ -97,7 +107,7 @@ type SendMessageOptions = {
export function useConversationComposerController({
activeSessionId,
appConfigChat,
draft,
getDraft,
composerAttachments,
isComposerAttachmentUploading,
selectedChatType,
@@ -268,7 +278,12 @@ export function useConversationComposerController({
answeredAt: null,
terminalAt: null,
});
syncConversationPreviewForRequest(activeSessionId, text, queuedAt);
syncConversationPreviewForRequest(activeSessionId, text, queuedAt, {
requestId,
mode: 'queue',
queueSize: 1,
jobMessage: '대기열 등록 중',
});
shouldStickToBottomRef.current = true;
setShowScrollToBottom(false);
@@ -304,6 +319,12 @@ export function useConversationComposerController({
answeredAt: null,
terminalAt: null,
});
syncConversationPreviewForRequest(activeSessionId, text, new Date().toISOString(), {
requestId,
mode: 'direct',
queueSize: 0,
jobMessage: '즉시 요청 실행 대기 중',
});
shouldStickToBottomRef.current = true;
setShowScrollToBottom(false);
@@ -374,7 +395,7 @@ export function useConversationComposerController({
return;
}
const trimmed = buildOutgoingMessageText(draftText ?? draft, composerAttachments).trim();
const trimmed = buildOutgoingMessageText(draftText ?? getDraft(), composerAttachments).trim();
if (!trimmed) {
return;
@@ -423,7 +444,7 @@ export function useConversationComposerController({
buildOutgoingMessageText,
composerAttachments,
createLocalMessage,
draft,
getDraft,
executeSendMessage,
isComposerAttachmentUploading,
messagesRef,

View File

@@ -48,6 +48,32 @@ function mergeConversationItemsPreservingRequestedSession(
contextDescription: item.contextDescription?.trim() || previousItem.contextDescription?.trim() || null,
lastMessagePreview: item.lastMessagePreview.trim() || previousItem.lastMessagePreview.trim(),
lastResponsePreview: item.lastResponsePreview.trim() || previousItem.lastResponsePreview.trim(),
currentRequestId:
item.currentRequestId?.trim() ||
((item.currentJobStatus == null || item.currentJobStatus === 'completed') ? previousItem.currentRequestId : null) ||
null,
currentJobStatus:
item.currentJobStatus ??
((previousItem.currentJobStatus === 'queued' || previousItem.currentJobStatus === 'started')
? previousItem.currentJobStatus
: null),
currentJobMessage:
item.currentJobMessage?.trim() ||
((item.currentJobStatus == null || item.currentJobStatus === 'completed') ? previousItem.currentJobMessage?.trim() : '') ||
null,
currentQueueSize:
item.currentQueueSize > 0
? item.currentQueueSize
: item.currentJobStatus === 'queued'
? Math.max(1, previousItem.currentQueueSize)
: previousItem.currentJobStatus === 'queued' && item.currentJobStatus == null
? Math.max(1, previousItem.currentQueueSize)
: item.currentQueueSize,
currentStatusUpdatedAt:
item.currentStatusUpdatedAt ||
((previousItem.currentJobStatus === 'queued' || previousItem.currentJobStatus === 'started')
? previousItem.currentStatusUpdatedAt
: null),
};
});
const normalizedRequestedSessionId = requestedSessionId.trim();

View File

@@ -359,8 +359,51 @@ export function useConversationRoomActionsController({
],
);
const handleClearConversation = useCallback(
async (sessionId: string) => {
try {
const item = await chatGateway.clearConversation(sessionId);
sessionMessageCacheRef.current.set(sessionId, []);
setConversationItems((previous) => previous.map((entry) => (entry.sessionId === sessionId ? item : entry)));
if (sessionId === activeSessionId) {
chatConnectionGateway.resetLastReceivedEventId(sessionId);
setMessages([]);
setRequestItems([]);
setDraft('');
setComposerAttachments([]);
setCopiedMessageId(null);
setActivePreviewId(null);
setIsPreviewModalOpen(false);
setActiveSystemStatus('채팅방 데이터를 초기화했습니다.');
setIsSystemStatusPending(false);
setIsResourceStripOpen(false);
}
} catch (error) {
messageApi.error(error instanceof Error ? error.message : '채팅방 데이터 초기화 중 오류가 발생했습니다.');
}
},
[
activeSessionId,
messageApi,
sessionMessageCacheRef,
setActivePreviewId,
setActiveSystemStatus,
setComposerAttachments,
setConversationItems,
setCopiedMessageId,
setDraft,
setIsPreviewModalOpen,
setIsResourceStripOpen,
setIsSystemStatusPending,
setMessages,
setRequestItems,
],
);
return {
cancelPendingRequest,
handleClearConversation,
deleteStoredRequest,
handleDeleteConversation,
handleRenameConversation,

View File

@@ -8,8 +8,8 @@ import type {
ChatMessage,
} from '../../mainChatPanel/types';
const INITIAL_CONVERSATION_REQUEST_PAGE_SIZE = 6;
const OLDER_CONVERSATION_REQUEST_PAGE_SIZE = 6;
const INITIAL_CONVERSATION_REQUEST_PAGE_SIZE = 8;
const OLDER_CONVERSATION_REQUEST_PAGE_SIZE = 8;
const CONVERSATION_DETAIL_RETRY_DELAYS_MS = [0, 250, 800];
function mergeConversationRequests(