llm 수정

This commit is contained in:
Macbook
2026-06-17 15:02:35 +09:00
parent 7a2509a045
commit f2ca6d0f3b
3 changed files with 98 additions and 54 deletions
@@ -811,6 +811,7 @@ export default function StrategyEvaluationPage({ theme = 'dark' }: Props) {
contextSummary={aiVerifySummary} contextSummary={aiVerifySummary}
verifyContext={aiVerifyContext} verifyContext={aiVerifyContext}
result={aiVerifyResult} result={aiVerifyResult}
theme={theme}
onRetry={() => { void runAiVerify(); }} onRetry={() => { void runAiVerify(); }}
/> />
</div> </div>
@@ -10,6 +10,8 @@ import type {
import { buildAiVerifyFixPoints } from '../../utils/strategyEvaluationAiVerify'; import { buildAiVerifyFixPoints } from '../../utils/strategyEvaluationAiVerify';
import type { StrategyEvaluationAiVerifyResponse } from '../../utils/strategyEvaluationAiVerify'; import type { StrategyEvaluationAiVerifyResponse } from '../../utils/strategyEvaluationAiVerify';
import type { Theme } from '../../types';
interface Props { interface Props {
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
@@ -19,6 +21,7 @@ interface Props {
verifyContext: StrategyEvaluationAiVerifyContext | null; verifyContext: StrategyEvaluationAiVerifyContext | null;
result: StrategyEvaluationAiVerifyResponse | null; result: StrategyEvaluationAiVerifyResponse | null;
onRetry?: () => void; onRetry?: () => void;
theme?: Theme;
} }
function renderAnalysisMarkdown(text: string): React.ReactNode { function renderAnalysisMarkdown(text: string): React.ReactNode {
@@ -227,6 +230,7 @@ const StrategyEvaluationAiVerifyModal: React.FC<Props> = ({
verifyContext, verifyContext,
result, result,
onRetry, onRetry,
theme = 'dark',
}) => { }) => {
const bodyRef = useRef<HTMLDivElement>(null); const bodyRef = useRef<HTMLDivElement>(null);
@@ -260,20 +264,20 @@ const StrategyEvaluationAiVerifyModal: React.FC<Props> = ({
const content = ( const content = (
<div <div
className="seval-ai-verify-overlay" className="seval-ai-verify-overlay app-popup-overlay--dim"
role="presentation" role="presentation"
onClick={handleBackdrop} onClick={handleBackdrop}
> >
<div <div
className="seval-ai-verify-modal" className={`seval-ai-verify-modal app-popup-shell se-page se-page--${theme}`}
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="seval-ai-verify-title" aria-labelledby="seval-ai-verify-title"
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
<header className="seval-ai-verify-head"> <header className="seval-ai-verify-head app-popup-header">
<div className="seval-ai-verify-head-main"> <div className="seval-ai-verify-head-main app-popup-header-left">
<h2 id="seval-ai-verify-title" className="seval-ai-verify-title"> <h2 id="seval-ai-verify-title" className="seval-ai-verify-title app-popup-header-title">
AI AI
</h2> </h2>
{contextSummary && ( {contextSummary && (
@@ -282,7 +286,7 @@ const StrategyEvaluationAiVerifyModal: React.FC<Props> = ({
</div> </div>
<button <button
type="button" type="button"
className="seval-ai-verify-close" className="seval-ai-verify-close app-popup-close"
aria-label="닫기" aria-label="닫기"
onClick={onClose} onClick={onClose}
> >
@@ -290,7 +294,7 @@ const StrategyEvaluationAiVerifyModal: React.FC<Props> = ({
</button> </button>
</header> </header>
<div ref={bodyRef} className="seval-ai-verify-body"> <div ref={bodyRef} className="seval-ai-verify-body app-popup-body">
{loading && ( {loading && (
<div className="seval-ai-verify-loading" aria-live="polite"> <div className="seval-ai-verify-loading" aria-live="polite">
<span className="btd-run-spinner seval-ai-verify-spinner" aria-hidden /> <span className="btd-run-spinner seval-ai-verify-spinner" aria-hidden />
+86 -47
View File
@@ -418,7 +418,7 @@
height: 14px; height: 14px;
} }
/* ── AI 검증 모달 ─────────────────────────────────────────────── */ /* ── AI 검증 모달 (body portal — 앱 테마·app-popup-shell 연동) ─────────────── */
.seval-ai-verify-overlay { .seval-ai-verify-overlay {
position: fixed; position: fixed;
inset: 0; inset: 0;
@@ -427,18 +427,42 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 24px; padding: 24px;
background: rgba(0, 0, 0, 0.55);
} }
.seval-ai-verify-modal { .seval-ai-verify-modal {
/* body 포털 — .se-page 테마 토큰 미상속 보정 */
--se-bg: var(--bg);
--se-bg-elevated: var(--bg2);
--se-bg-muted: var(--bg3);
--se-text: var(--text);
--se-text-muted: var(--text2);
--se-text-dim: var(--text3);
--se-border: var(--border);
--se-accent: var(--accent);
--se-accent-hover: var(--accent-h);
--se-gold: #e6c200;
--se-input-bg: color-mix(in srgb, var(--bg3) 88%, transparent);
--se-panel-bg: var(--bg2);
--btd-gold: var(--se-gold, #e6c200);
--app-popup-accent: color-mix(in srgb, var(--btd-gold, #e6c200) 40%, var(--accent, #3f7ef5));
position: relative;
width: min(720px, 100%); width: min(720px, 100%);
max-height: min(88vh, 820px); max-height: min(88vh, 820px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-radius: 12px; color: var(--text, #c0caf5);
border: 1px solid var(--se-border); font-size: 13px;
background: var(--se-panel-bg, #1a1d24); }
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
.seval-ai-verify-modal.se-page--light {
--se-gold: #f57f17;
--btd-gold: var(--se-gold);
}
.seval-ai-verify-modal.se-page--blue {
--se-gold: #ffd54f;
--btd-gold: var(--se-gold);
} }
.seval-ai-verify-head { .seval-ai-verify-head {
@@ -446,38 +470,41 @@
align-items: flex-start; align-items: flex-start;
justify-content: space-between; justify-content: space-between;
gap: 12px; gap: 12px;
padding: 16px 18px 12px; padding: 12px 16px;
border-bottom: 1px solid var(--se-border); flex-shrink: 0;
cursor: default;
border-bottom: 1px solid var(--border, rgba(122, 162, 247, 0.12));
background: linear-gradient(
180deg,
color-mix(in srgb, var(--app-popup-accent, var(--accent, #3f7ef5)) 16%, transparent) 0%,
color-mix(in srgb, var(--app-popup-accent, var(--accent, #3f7ef5)) 5%, transparent) 28px,
var(--bg3, #1f2335) 100%
);
} }
.seval-ai-verify-title { .seval-ai-verify-title {
margin: 0; margin: 0;
font-size: 1.05rem; font-size: 14px;
font-weight: 600; font-weight: 700;
color: var(--se-text); color: var(--text, #c0caf5);
letter-spacing: 0.02em;
} }
.seval-ai-verify-summary { .seval-ai-verify-summary {
margin: 6px 0 0; margin: 6px 0 0;
font-size: 0.78rem; font-size: 0.78rem;
color: var(--se-text-muted); color: var(--text2, #9aa5ce);
line-height: 1.45; line-height: 1.45;
} }
.seval-ai-verify-close { .seval-ai-verify-close {
border: none; font-size: 16px;
background: transparent;
color: var(--se-text-muted);
font-size: 1.5rem;
line-height: 1;
cursor: pointer;
padding: 0 4px;
} }
.seval-ai-verify-body { .seval-ai-verify-body {
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: 16px 18px; padding: 14px 16px 16px;
min-height: 200px; min-height: 200px;
} }
@@ -488,7 +515,11 @@
gap: 10px; gap: 10px;
padding: 32px 12px; padding: 32px 12px;
text-align: center; text-align: center;
color: var(--se-text-muted); color: var(--text, #c0caf5);
}
.seval-ai-verify-loading p {
margin: 0;
} }
.seval-ai-verify-spinner { .seval-ai-verify-spinner {
@@ -498,13 +529,14 @@
.seval-ai-verify-loading-hint { .seval-ai-verify-loading-hint {
font-size: 0.78rem; font-size: 0.78rem;
opacity: 0.85; color: var(--text2, #9aa5ce);
} }
.seval-ai-verify-error { .seval-ai-verify-error {
padding: 12px; padding: 12px;
border-radius: 8px; border-radius: 8px;
background: color-mix(in srgb, #ef5350 12%, transparent); background: color-mix(in srgb, #ef5350 14%, var(--bg2, #1e222d));
border: 1px solid color-mix(in srgb, #ef5350 35%, var(--border, transparent));
color: #ffb4ab; color: #ffb4ab;
} }
@@ -512,9 +544,9 @@
margin-top: 12px; margin-top: 12px;
padding: 6px 14px; padding: 6px 14px;
border-radius: 6px; border-radius: 6px;
border: 1px solid var(--se-border); border: 1px solid var(--border, var(--se-border));
background: var(--se-input-bg); background: var(--bg3, var(--se-input-bg));
color: var(--se-text); color: var(--text, var(--se-text));
cursor: pointer; cursor: pointer;
} }
@@ -522,7 +554,7 @@
display: flex; display: flex;
gap: 12px; gap: 12px;
font-size: 0.75rem; font-size: 0.75rem;
color: var(--se-text-muted); color: var(--text2, var(--se-text-muted));
margin-bottom: 12px; margin-bottom: 12px;
} }
@@ -530,7 +562,7 @@
margin: 16px 0 8px; margin: 16px 0 8px;
font-size: 0.92rem; font-size: 0.92rem;
font-weight: 600; font-weight: 600;
color: var(--btd-gold, var(--se-gold)); color: var(--btd-gold, var(--se-gold, #e6c200));
} }
.seval-ai-verify-h3:first-child { .seval-ai-verify-h3:first-child {
@@ -541,7 +573,7 @@
margin: 0 0 8px; margin: 0 0 8px;
font-size: 0.84rem; font-size: 0.84rem;
line-height: 1.55; line-height: 1.55;
color: var(--se-text); color: var(--text, var(--se-text));
} }
.seval-ai-verify-list { .seval-ai-verify-list {
@@ -549,7 +581,7 @@
padding-left: 1.2rem; padding-left: 1.2rem;
font-size: 0.84rem; font-size: 0.84rem;
line-height: 1.5; line-height: 1.5;
color: var(--se-text); color: var(--text, var(--se-text));
} }
.seval-ai-verify-foot { .seval-ai-verify-foot {
@@ -557,14 +589,15 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 12px; gap: 12px;
padding: 12px 18px 16px; padding: 12px 16px 14px;
border-top: 1px solid var(--se-border); border-top: 1px solid var(--border, var(--se-border));
background: color-mix(in srgb, var(--bg3, #1f2335) 65%, var(--bg2, #1e222d));
} }
.seval-ai-verify-footnote { .seval-ai-verify-footnote {
margin: 0; margin: 0;
font-size: 0.72rem; font-size: 0.72rem;
color: var(--se-text-muted); color: var(--text2, var(--se-text-muted));
line-height: 1.4; line-height: 1.4;
} }
@@ -572,10 +605,16 @@
flex-shrink: 0; flex-shrink: 0;
padding: 6px 16px; padding: 6px 16px;
border-radius: 6px; border-radius: 6px;
border: 1px solid var(--se-border); border: 1px solid var(--border, var(--se-border));
background: var(--se-input-bg); background: var(--bg3, var(--se-input-bg));
color: var(--se-text); color: var(--text, var(--se-text));
cursor: pointer; cursor: pointer;
transition: background 0.15s, border-color 0.15s;
}
.seval-ai-verify-close-btn:hover {
background: color-mix(in srgb, var(--accent, #3f7ef5) 12%, var(--bg3, #1f2335));
border-color: color-mix(in srgb, var(--accent, #3f7ef5) 35%, var(--border));
} }
/* ── AI 검증 수정 포인트 (Cursor) ── */ /* ── AI 검증 수정 포인트 (Cursor) ── */
@@ -636,10 +675,10 @@
} }
.seval-ai-verify-fixpoint { .seval-ai-verify-fixpoint {
border: 1px solid var(--se-border); border: 1px solid var(--border, var(--se-border));
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
background: color-mix(in srgb, var(--se-input-bg) 80%, transparent); background: color-mix(in srgb, var(--bg2, var(--se-input-bg)) 92%, var(--bg, #1a1b26));
} }
.seval-ai-verify-fixpoint-toggle { .seval-ai-verify-fixpoint-toggle {
@@ -650,7 +689,7 @@
padding: 10px 12px; padding: 10px 12px;
border: none; border: none;
background: transparent; background: transparent;
color: var(--se-text); color: var(--text, var(--se-text));
text-align: left; text-align: left;
cursor: pointer; cursor: pointer;
font-size: 0.82rem; font-size: 0.82rem;
@@ -705,12 +744,12 @@
margin: 0; margin: 0;
padding: 8px 10px; padding: 8px 10px;
border-radius: 6px; border-radius: 6px;
border: 1px solid var(--se-border); border: 1px solid var(--border, var(--se-border));
background: var(--se-panel-bg, #14161a); background: color-mix(in srgb, var(--bg, #1a1b26) 55%, var(--bg2, #24283b));
font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.72rem; font-size: 0.72rem;
line-height: 1.5; line-height: 1.5;
color: var(--se-text); color: var(--text, var(--se-text));
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-word; word-break: break-word;
max-height: 220px; max-height: 220px;
@@ -719,7 +758,7 @@
.seval-ai-verify-ta4j { .seval-ai-verify-ta4j {
margin-top: 16px; margin-top: 16px;
border: 1px solid var(--se-border); border: 1px solid var(--border, var(--se-border));
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
} }
@@ -731,8 +770,8 @@
width: 100%; width: 100%;
padding: 10px 12px; padding: 10px 12px;
border: none; border: none;
background: color-mix(in srgb, var(--se-input-bg) 90%, transparent); background: color-mix(in srgb, var(--bg3, var(--se-input-bg)) 88%, transparent);
color: var(--se-text); color: var(--text, var(--se-text));
font-size: 0.82rem; font-size: 0.82rem;
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
@@ -748,7 +787,7 @@
flex-wrap: wrap; flex-wrap: wrap;
gap: 10px 16px; gap: 10px 16px;
font-size: 0.78rem; font-size: 0.78rem;
color: var(--se-text-muted); color: var(--text2, var(--se-text-muted));
margin-bottom: 8px; margin-bottom: 8px;
} }
@@ -756,7 +795,7 @@
margin: 0 0 8px; margin: 0 0 8px;
font-size: 0.78rem; font-size: 0.78rem;
line-height: 1.45; line-height: 1.45;
color: var(--se-text); color: var(--text, var(--se-text));
} }
.seval-ai-verify-ta4j-err { .seval-ai-verify-ta4j-err {