fix(compression): show engine preview output (#4128)

Integrated into release/v3.8.29
This commit is contained in:
Demiurge The Single
2026-06-18 06:22:10 +03:00
committed by GitHub
parent 3919661bc2
commit 677d447a89
2 changed files with 119 additions and 10 deletions

View File

@@ -31,10 +31,24 @@ interface Analytics {
days: number;
}
interface PreviewDiffSegment {
type?: string;
value?: string;
text?: string;
content?: string;
original?: string;
compressed?: string;
before?: string;
after?: string;
}
interface PreviewResult {
original?: string;
compressed?: string;
originalTokens: number;
compressedTokens: number;
savingsPct: number;
diff?: PreviewDiffSegment[];
}
// ── Default preview sample ────────────────────────────────────────────────
@@ -55,6 +69,27 @@ function StatCard({ label, value }: { label: string; value: string }) {
);
}
function renderDiffSegment(segment: PreviewDiffSegment, index: number) {
const label = segment.type ?? "change";
const text =
segment.value ??
segment.text ??
segment.content ??
[segment.original ?? segment.before, segment.compressed ?? segment.after]
.filter(Boolean)
.join(" → ") ??
"";
return (
<div key={`${label}-${index}`} className="rounded border border-border bg-background p-2">
<span className="mr-2 rounded bg-muted px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-text-muted">
{label}
</span>
<span className="whitespace-pre-wrap break-words text-text">{text}</span>
</div>
);
}
// ── Main component ────────────────────────────────────────────────────────
export function EngineConfigPage({ engineId }: { engineId: string }) {
@@ -321,16 +356,46 @@ export function EngineConfigPage({ engineId }: { engineId: string }) {
</div>
{previewError && <p className="text-xs text-destructive">{previewError}</p>}
{preview && (
<div className="flex gap-4 text-sm pt-1">
<span className="text-text-muted">
Original tokens: <strong className="text-text">{preview.originalTokens}</strong>
</span>
<span className="text-text-muted">
Compressed tokens: <strong className="text-text">{preview.compressedTokens}</strong>
</span>
<span className="text-text-muted">
Savings: <strong className="text-primary">{preview.savingsPct.toFixed(1)}%</strong>
</span>
<div className="flex flex-col gap-3 pt-1 text-sm">
<div className="flex flex-wrap gap-4">
<span className="text-text-muted">
Original tokens: <strong className="text-text">{preview.originalTokens}</strong>
</span>
<span className="text-text-muted">
Compressed tokens: <strong className="text-text">{preview.compressedTokens}</strong>
</span>
<span className="text-text-muted">
Savings: <strong className="text-primary">{preview.savingsPct.toFixed(1)}%</strong>
</span>
</div>
<div className="grid gap-3 md:grid-cols-2">
<div className="flex flex-col gap-1">
<h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
Original
</h3>
<pre className="max-h-72 overflow-auto rounded border border-border bg-background p-3 whitespace-pre-wrap break-words text-text">
{preview.original ?? ""}
</pre>
</div>
<div className="flex flex-col gap-1">
<h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
Compressed
</h3>
<pre className="max-h-72 overflow-auto rounded border border-border bg-background p-3 whitespace-pre-wrap break-words text-text">
{preview.compressed ?? ""}
</pre>
</div>
</div>
{preview.diff && preview.diff.length > 0 && (
<div className="flex flex-col gap-2" data-testid="compression-preview-diff">
<h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
Diff
</h3>
<div className="flex max-h-72 flex-col gap-2 overflow-auto rounded border border-border p-2">
{preview.diff.map(renderDiffSegment)}
</div>
</div>
)}
</div>
)}
</div>

View File

@@ -114,6 +114,19 @@ function setupFetchMock() {
headers: { "Content-Type": "application/json" },
});
}
if (url.includes("/api/compression/preview")) {
return new Response(
JSON.stringify({
original: "The original context contains duplicated details and verbose wording.",
compressed: "Original context, deduplicated.",
originalTokens: 11,
compressedTokens: 4,
savingsPct: 63.6,
diff: [{ type: "removed", text: "duplicated details and verbose wording" }],
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
}
return new Response(JSON.stringify({}), { status: 404 });
});
}
@@ -199,6 +212,37 @@ describe("EngineConfigPage", () => {
expect(container.textContent).toContain("Enable layer");
});
it("renders preview original, compressed text, and diff returned by the API", async () => {
setupFetchMock();
const { EngineConfigPage } =
await import("../../../src/shared/components/compression/EngineConfigPage");
let container!: HTMLElement;
await act(async () => {
container = mountInContainer(<EngineConfigPage engineId="headroom" />);
});
await act(async () => {
await Promise.resolve();
});
const previewButton = Array.from(container.querySelectorAll("button")).find(
(button) => button.textContent === "Preview"
);
expect(previewButton).toBeTruthy();
await act(async () => {
previewButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
await Promise.resolve();
});
expect(container.textContent).toContain(
"The original context contains duplicated details and verbose wording."
);
expect(container.textContent).toContain("Original context, deduplicated.");
expect(container.textContent).toContain("Diff");
expect(container.textContent).toContain("duplicated details and verbose wording");
});
it("shows empty-state text when analytics returns runs=0", async () => {
setupFetchMock();
const { EngineConfigPage } =