chore: test deploy snapshot
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user