feat: refine codex live chat context flows
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user