wip: phase_z2 evidence 파이프라인 + matching 실험(phase2~26) + 프론트 trace 패널 진행분 스냅샷
- src: phase_z2 composition/mapper/pipeline/placement_planner/retry, ai_fallback(prompts/schema/validate), mdx_text_atoms 신규 - Front: PipelineTracePanel 신규, FramePanel/SlideCanvas/Home/designAgentApi 등 갱신 + 테스트 4종 추가 - templates/phase_z2: catalog(component_expansion_registry, node_slot_mapping 신규), frames, families, slide_base 갱신 - tests/matching: phase2~26 매칭 실험 스크립트·리포트·온톨로지 전체 (미커밋 진행분) - tests: b4_v4 evidence, task5~28.5 시리즈, regression(imp95 baseline) 등 신규 테스트 대량 추가 - docs/reference: MDX 구조 인벤토리, MDX→Frame 구조 계약 문서 - scripts: mdx 계약/parity/coverage/viewport 체크, gitea comment, run sync 유틸 - .gitignore: tmp*.json, chromedriver, .orchestrator, *.pkl, Front_test* 등 임시/스냅샷 제외 미완성 작업의 보존용 스냅샷 커밋 (2026-07-02) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
97b7833a1b
commit
b836e79ee1
527 files changed
+673036
-717
No files matched your search
@@ -0,0 +1,216 @@
|
||||
import { AlertTriangle, CheckCircle2, GitBranch, Layers3 } from "lucide-react";
|
||||
import type React from "react";
|
||||
import type { AiTraceSummary, PipelineTraceSummary } from "../services/designAgentApi";
|
||||
|
||||
interface PipelineTracePanelProps {
|
||||
trace: PipelineTraceSummary | null | undefined;
|
||||
aiTrace?: AiTraceSummary | null;
|
||||
}
|
||||
|
||||
const stateClass: Record<string, string> = {
|
||||
rendered: "bg-emerald-50 text-emerald-700 border-emerald-200",
|
||||
render_blocked: "bg-red-50 text-red-700 border-red-200",
|
||||
filtered: "bg-amber-50 text-amber-700 border-amber-200",
|
||||
covered_not_rendered: "bg-orange-50 text-orange-700 border-orange-200",
|
||||
uncovered: "bg-slate-50 text-slate-500 border-slate-200",
|
||||
};
|
||||
|
||||
function Chip({ children, tone = "slate" }: { children: React.ReactNode; tone?: "slate" | "red" | "green" | "amber" }) {
|
||||
const tones = {
|
||||
slate: "bg-slate-100 text-slate-600",
|
||||
red: "bg-red-100 text-red-700",
|
||||
green: "bg-emerald-100 text-emerald-700",
|
||||
amber: "bg-amber-100 text-amber-700",
|
||||
};
|
||||
return (
|
||||
<span className={`inline-flex items-center rounded px-1.5 py-0.5 text-[9px] font-black uppercase ${tones[tone]}`}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PipelineTracePanel({ trace, aiTrace }: PipelineTracePanelProps) {
|
||||
if (!trace) {
|
||||
return (
|
||||
<div className="h-full flex items-center justify-center bg-slate-50 p-8 text-center text-slate-400">
|
||||
<div>
|
||||
<GitBranch className="mx-auto mb-3 h-10 w-10 opacity-20" />
|
||||
<p className="text-[10px] font-black uppercase tracking-[0.18em]">No Trace Loaded</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-full overflow-y-auto bg-white p-4 text-slate-700">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<GitBranch className="h-4 w-4 text-blue-500" />
|
||||
<h3 className="text-[10px] font-black uppercase tracking-widest text-slate-500">Pipeline Trace</h3>
|
||||
</div>
|
||||
<Chip tone={trace.warnings.length > 0 ? "amber" : "green"}>{trace.status}</Chip>
|
||||
</div>
|
||||
|
||||
{trace.warnings.length > 0 && (
|
||||
<div className="mb-4 rounded border border-amber-200 bg-amber-50 p-3">
|
||||
<div className="mb-1 flex items-center gap-1.5 text-[10px] font-black uppercase text-amber-700">
|
||||
<AlertTriangle className="h-3.5 w-3.5" />
|
||||
Warnings
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{trace.warnings.map((warning) => (
|
||||
<Chip key={warning} tone="amber">{warning}</Chip>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<section className="mb-5">
|
||||
<div className="mb-2 flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest text-slate-400">
|
||||
<Layers3 className="h-3.5 w-3.5" />
|
||||
Sections
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{trace.sections.map((section) => (
|
||||
<div key={section.id} className={`rounded border p-2 ${stateClass[section.state] ?? stateClass.uncovered}`}>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="font-mono text-[11px] font-bold">{section.id}</span>
|
||||
<span className="text-[9px] font-black uppercase">{section.state}</span>
|
||||
</div>
|
||||
{section.title && <div className="mt-1 text-[11px] leading-snug">{section.title}</div>}
|
||||
{section.child_ids.length > 0 && (
|
||||
<div className="mt-1 text-[10px] text-slate-500">children: {section.child_ids.join(", ")}</div>
|
||||
)}
|
||||
{section.reasons.length > 0 && (
|
||||
<div className="mt-2 flex flex-wrap gap-1">
|
||||
{section.reasons.map((reason) => (
|
||||
<Chip key={reason} tone={section.state === "render_blocked" ? "red" : "amber"}>
|
||||
{reason}
|
||||
</Chip>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mb-5">
|
||||
<div className="mb-2 text-[10px] font-black uppercase tracking-widest text-slate-400">Units</div>
|
||||
<div className="space-y-2">
|
||||
{trace.units.map((unit) => (
|
||||
<div key={unit.unit_id} className="rounded border border-slate-200 bg-slate-50 p-2">
|
||||
<div className="font-mono text-[11px] font-bold text-slate-700">{unit.unit_id || "(empty unit)"}</div>
|
||||
<div className="mt-1 grid grid-cols-2 gap-x-2 gap-y-1 text-[10px]">
|
||||
<span>frame</span><span className="font-mono">{unit.selected_frame ?? "-"}</span>
|
||||
<span>candidates</span><span className="font-mono">{unit.candidate_count}</span>
|
||||
<span>path</span><span className="font-mono">{unit.selection_path ?? "-"}</span>
|
||||
<span>label</span><span className="font-mono">{unit.label ?? "-"}</span>
|
||||
</div>
|
||||
{unit.warnings.length > 0 && (
|
||||
<div className="mt-2 flex flex-wrap gap-1">
|
||||
{unit.warnings.map((warning) => <Chip key={warning} tone="amber">{warning}</Chip>)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div className="mb-2 text-[10px] font-black uppercase tracking-widest text-slate-400">Zones / Render</div>
|
||||
<div className="space-y-2">
|
||||
{trace.zones.map((zone) => {
|
||||
const filled = zone.slot_status === "filled";
|
||||
return (
|
||||
<div key={zone.position} className="rounded border border-slate-200 bg-white p-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-mono text-[11px] font-bold">{zone.position}</span>
|
||||
<Chip tone={filled ? "green" : "red"}>{zone.slot_status}</Chip>
|
||||
</div>
|
||||
<div className="mt-1 text-[10px] text-slate-500">sections: {zone.source_section_ids.join(", ") || "-"}</div>
|
||||
<div className="mt-1 text-[10px] text-slate-500">template: <span className="font-mono">{zone.template_id ?? "-"}</span></div>
|
||||
<div className="mt-1 text-[10px] text-slate-500">slot keys: {zone.slot_key_count}</div>
|
||||
{zone.warnings.length > 0 ? (
|
||||
<div className="mt-2 flex flex-wrap gap-1">
|
||||
{zone.warnings.map((warning) => <Chip key={warning} tone="red">{warning}</Chip>)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-2 flex items-center gap-1 text-[10px] text-emerald-600">
|
||||
<CheckCircle2 className="h-3 w-3" />
|
||||
render payload ready
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mt-5">
|
||||
<div className="mb-2 text-[10px] font-black uppercase tracking-widest text-slate-400">AI Status</div>
|
||||
{!aiTrace ? (
|
||||
<div className="rounded border border-slate-200 bg-slate-50 p-3 text-[11px] text-slate-500">
|
||||
AI trace not loaded.
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded border border-slate-200 bg-white p-3">
|
||||
<div className="mb-2 flex flex-wrap gap-1">
|
||||
<Chip tone={aiTrace.artifact_present ? "green" : "red"}>
|
||||
{aiTrace.artifact_present ? "artifact" : "missing"}
|
||||
</Chip>
|
||||
<Chip tone={aiTrace.ai_enabled === false ? "amber" : aiTrace.ai_enabled ? "green" : "slate"}>
|
||||
enabled {aiTrace.ai_enabled === null ? "unknown" : String(aiTrace.ai_enabled)}
|
||||
</Chip>
|
||||
<Chip tone={aiTrace.ai_called_count > 0 ? "green" : "slate"}>
|
||||
called {aiTrace.ai_called_count}
|
||||
</Chip>
|
||||
<Chip tone={aiTrace.eligible_count > 0 ? "amber" : "slate"}>
|
||||
eligible {aiTrace.eligible_count}
|
||||
</Chip>
|
||||
<Chip tone={aiTrace.error_count > 0 ? "red" : "slate"}>
|
||||
errors {aiTrace.error_count}
|
||||
</Chip>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-x-2 gap-y-1 text-[10px] text-slate-500">
|
||||
<span>status</span><span className="font-mono">{aiTrace.status}</span>
|
||||
<span>coverage</span><span className="font-mono">{aiTrace.coverage_status ?? "-"}</span>
|
||||
<span>provider</span><span className="font-mono">{aiTrace.provider ?? "-"}</span>
|
||||
<span>human review</span><span className="font-mono">{String(aiTrace.human_review_required)}</span>
|
||||
</div>
|
||||
{Object.keys(aiTrace.skip_reasons).length > 0 && (
|
||||
<div className="mt-3">
|
||||
<div className="mb-1 text-[10px] font-black uppercase text-slate-400">Skip Reasons</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{Object.entries(aiTrace.skip_reasons).map(([reason, count]) => (
|
||||
<Chip key={reason} tone={reason === "called" ? "green" : "slate"}>
|
||||
{reason}: {count}
|
||||
</Chip>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{aiTrace.units.length > 0 && (
|
||||
<div className="mt-3 space-y-2">
|
||||
{aiTrace.units.map((unit) => (
|
||||
<div key={`${unit.unit_index}-${unit.source_section_ids.join("+")}`} className="rounded bg-slate-50 p-2 text-[10px]">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-mono font-bold">{unit.source_section_ids.join("+") || `unit-${unit.unit_index}`}</span>
|
||||
<Chip tone={unit.ai_called ? "green" : "slate"}>{unit.ai_called ? "called" : "not called"}</Chip>
|
||||
</div>
|
||||
<div className="mt-1 grid grid-cols-2 gap-x-2 gap-y-1 text-slate-500">
|
||||
<span>route</span><span className="font-mono">{unit.route_hint ?? "-"}</span>
|
||||
<span>skip</span><span className="font-mono">{unit.skip_reason ?? "-"}</span>
|
||||
<span>apply</span><span className="font-mono">{unit.apply_status ?? "-"}</span>
|
||||
<span>error</span><span className="font-mono">{unit.error ?? "-"}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user