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

@@ -2,6 +2,7 @@ import type { Dispatch, SetStateAction } from 'react';
import { appendClientIdHeader, getOrCreateClientId } from '../clientIdentity';
import { getRegisteredAccessToken, hasRegisteredAccessTokenAccess } from '../tokenAccess';
import { reportClientError } from '../errorLogApi';
import { copyTextToClipboard } from '../../../utils/clipboard';
import type {
ChatActivityEvent,
ChatConversationActivityLog,
@@ -839,32 +840,7 @@ export async function diagnoseConnectionFailure(targetUrl: string, closeEvent?:
}
export async function copyText(text: string) {
if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
if (typeof document === 'undefined') {
throw new Error('클립보드를 사용할 수 없습니다.');
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
const copied = document.execCommand('copy');
if (!copied) {
throw new Error('복사 명령이 거부되었습니다.');
}
} finally {
document.body.removeChild(textarea);
}
return copyTextToClipboard(text);
}
export type PreviewCopyResult = 'text' | 'image' | 'url';
@@ -1419,6 +1395,23 @@ export async function deleteChatConversationRoom(sessionId: string) {
return response;
}
export async function clearChatConversationRoom(sessionId: string) {
const clientId = getOrCreateClientId();
const response = await requestChatApi<{ ok: boolean; item: ChatConversationSummary }>(
`/conversations/${encodeURIComponent(sessionId)}/clear`,
{
method: 'POST',
},
);
invalidateChatConversationListCache();
return {
...response.item,
notifyOffline: resolveSyncedChatOfflineNotificationSetting(response.item.sessionId, response.item.notifyOffline, clientId),
};
}
export async function deleteChatConversationRequest(sessionId: string, requestId: string) {
const response = await requestChatApi<{ ok: boolean; deleted: boolean; sessionId: string; requestId: string }>(
`/conversations/${encodeURIComponent(sessionId)}/requests/${encodeURIComponent(requestId)}`,
@@ -1450,13 +1443,16 @@ function areChatMessagesEquivalent(left: ChatMessage[], right: ChatMessage[]) {
return left.every((message, index) => {
const other = right[index];
const leftParts = JSON.stringify(message.parts ?? []);
const rightParts = JSON.stringify(other?.parts ?? []);
return (
other &&
message.id === other.id &&
message.author === other.author &&
message.text === other.text &&
message.timestamp === other.timestamp
message.timestamp === other.timestamp &&
leftParts === rightParts
);
});
}
@@ -1491,6 +1487,7 @@ export function upsertChatMessage(previous: ChatMessage[], incoming: ChatMessage
...existingMessage,
...incoming,
text: nextText,
parts: incoming.parts ?? existingMessage.parts ?? [],
deliveryStatus: null,
retryCount: 0,
};