chore: test deploy snapshot

This commit is contained in:
2026-05-29 07:57:56 +09:00
parent 1e7212b862
commit b242d91ecb
14 changed files with 753 additions and 47 deletions

View File

@@ -62,6 +62,7 @@ import { extractHiddenPreviewUrls, stripHiddenPreviewTags } from './previewMarke
import { normalizeChatResourceUrl } from './chatResourceUrl';
import { copyPreviewContent, copyText, isExecutionFailureMessage, isMissingRequestMessage, sharePreviewLink } from './chatUtils';
import { ChatLinkCardPreview } from './ChatLinkCardPreview';
import { normalizeCodexModel } from '../codexModelOptions';
import { ChatActivityChecklist, buildChatActivityChecklistEntries } from './ChatActivityChecklist';
import { describeExecutorCommand } from './executorActivitySummary';
import { buildComposerFilePickKey } from './composerFilePickKey';
@@ -105,6 +106,26 @@ type CodexModelOption = {
description: string;
};
type ChatConversationRequestWithModel = ChatConversationRequest & {
codexModel?: string | null;
};
function resolveRequestModelTokenUsage(request: ChatConversationRequest) {
return Math.max(
0,
Math.round(
Number(
request.usageSnapshot?.tokenTotals?.total ?? request.usageSnapshot?.totalTokens ?? request.totalTokens ?? 0,
) || 0,
),
);
}
function resolveRequestCodexModel(request: ChatConversationRequest) {
const requestWithModel = request as ChatConversationRequestWithModel;
return normalizeCodexModel(requestWithModel.codexModel?.trim() || '');
}
type PreviewOption = {
id: string;
label: string;
@@ -2951,6 +2972,7 @@ type ChatConversationViewProps = {
composerAssistModalTitle?: string;
chatTypeOptions: ChatTypeOption[];
codexModelOptions: CodexModelOption[];
sharedComposerModelTokenLimits?: Record<string, number | null>;
previewItems: PreviewOption[];
isResourceStripOpen: boolean;
showResourceStrip?: boolean;
@@ -3508,6 +3530,7 @@ export function ChatConversationView({
composerAssistModalTitle,
chatTypeOptions,
codexModelOptions,
sharedComposerModelTokenLimits,
previewItems,
isResourceStripOpen,
showResourceStrip = true,
@@ -3974,6 +3997,46 @@ export function ChatConversationView({
const isChatTypeReadonly = isChatTypeSelectionLocked;
const selectedChatTypeOption = chatTypeOptions.find((option) => option.value === selectedChatTypeId) ?? null;
const sharedComposerChatTypeLabel = selectedChatTypeOption?.label?.trim() || '컨텍스트 없음';
const normalizedSelectedCodexModel = normalizeCodexModel(selectedCodexModel);
const selectedCodexModelTokenLimit =
sharedComposerModelTokenLimits?.[normalizedSelectedCodexModel] ??
sharedComposerModelTokenLimits?.[selectedCodexModel] ??
null;
const normalizedSelectedCodexModelTokenLimit = Number.isFinite(selectedCodexModelTokenLimit)
? Math.max(0, Math.round(Number(selectedCodexModelTokenLimit)))
: null;
const sharedComposerModelUsedTokens = useMemo(() => {
if (!useSharedComposerChrome) {
return 0;
}
let total = 0;
requestStateMap.forEach((request) => {
if (resolveRequestCodexModel(request) !== normalizedSelectedCodexModel) {
return;
}
total += resolveRequestModelTokenUsage(request);
});
return total;
}, [requestStateMap, normalizedSelectedCodexModel, useSharedComposerChrome]);
const sharedComposerModelRemainingTokensText = useMemo(() => {
if (normalizedSelectedCodexModelTokenLimit === null) {
return `이번 세션 사용량 ${sharedComposerModelUsedTokens.toLocaleString('ko-KR')} 토큰`;
}
const remainingTokens = Math.max(0, normalizedSelectedCodexModelTokenLimit - sharedComposerModelUsedTokens);
return `잔여 ${remainingTokens.toLocaleString('ko-KR')} / ${normalizedSelectedCodexModelTokenLimit.toLocaleString(
'ko-KR',
)} 토큰`;
}, [normalizedSelectedCodexModelTokenLimit, sharedComposerModelUsedTokens]);
const sharedComposerModelTokenLimitLabel =
sharedComposerModelRemainingTokensText && sharedComposerModelRemainingTokensText.length > 0
? sharedComposerModelRemainingTokensText
: '토큰 정보 없음';
const pendingManualCompletionActionKeySet = useMemo(
() => new Set(pendingManualCompletionActionKeys),
[pendingManualCompletionActionKeys],
@@ -7973,6 +8036,26 @@ export function ChatConversationView({
disabled
/>
</div>
<div className="app-chat-panel__composer-type">
<Select
value={selectedCodexModel}
placeholder="Codex 모델 선택"
options={codexModelOptions.map((option) => ({
value: option.value,
label: (
<div className="app-chat-panel__type-option">
<span>{option.label}</span>
</div>
),
}))}
getPopupContainer={(triggerNode) => triggerNode.closest('.app-chat-panel') ?? document.body}
disabled={isComposerDisabled || codexModelOptions.length === 0}
onChange={onSelectCodexModel}
/>
</div>
<div className="app-chat-panel__composer-model-token" title={sharedComposerModelTokenLimitLabel}>
<span>{sharedComposerModelTokenLimitLabel}</span>
</div>
<div className="app-chat-panel__composer-actions app-chat-panel__composer-actions--shared">
<div className="app-chat-panel__composer-action-buttons">
<Button