mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
fix(compression): show engine preview output (#4128)
Integrated into release/v3.8.29
This commit is contained in:
committed by
GitHub
parent
3919661bc2
commit
677d447a89
@@ -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>
|
||||
|
||||
@@ -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 } =
|
||||
|
||||
Reference in New Issue
Block a user