mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-03 22:02:08 +03:00
feat(compression): playground fidelity-gate toggle + lane rejection display
This commit is contained in:
committed by
Diego Rodrigues de Sa e Souza
parent
8df1aff301
commit
ce802fa296
@@ -7,6 +7,8 @@ import { PlaygroundInput, LANE_ENGINES } from "./PlaygroundInput";
|
||||
export interface PlayViewProps { text: string; onText: (t: string) => void; laneEngines?: readonly string[]; }
|
||||
|
||||
function laneStatus(l: Lane): string {
|
||||
const rejected = l.run?.steps?.find((s) => s.rejected);
|
||||
if (rejected) return `⚠ rejeitado: ${rejected.rejectReason ?? ""}`;
|
||||
return l.error ? "⚠ erro" : l.run ? `−${l.run.savingsPercent}%` : "—";
|
||||
}
|
||||
|
||||
@@ -31,15 +33,16 @@ function LaneList({ lanes, onSelect }: { lanes: Lane[]; onSelect: (e: string) =>
|
||||
export function PlayView({ text, onText, laneEngines = LANE_ENGINES }: PlayViewProps) {
|
||||
const [active, setActive] = useState<string[]>(["rtk", "caveman"]);
|
||||
const [selectedLane, setSelectedLane] = useState<string | null>(null);
|
||||
const [fidelityGate, setFidelityGate] = useState(false);
|
||||
const { batch, loading, run } = usePreviewCompression();
|
||||
const messages = [{ role: "user", content: text }];
|
||||
const toggle = (e: string) => setActive((a) => (a.includes(e) ? a.filter((x) => x !== e) : [...a, e]));
|
||||
const onRun = () => run({ messages, laneEngines: [...laneEngines], activeEngines: orderByStack(active, laneEngines) });
|
||||
const onRun = () => run({ messages, laneEngines: [...laneEngines], activeEngines: orderByStack(active, laneEngines), fidelityGate });
|
||||
const activeDiff = resolveActiveDiff(batch, selectedLane);
|
||||
return (
|
||||
<div className="flex h-full gap-3">
|
||||
<div className="w-[260px] shrink-0">
|
||||
<PlaygroundInput text={text} onText={onText} active={active} onToggleActive={toggle} onRun={onRun} loading={loading} />
|
||||
<PlaygroundInput text={text} onText={onText} active={active} onToggleActive={toggle} onRun={onRun} loading={loading} fidelityGate={fidelityGate} onToggleFidelity={() => setFidelityGate((v) => !v)} />
|
||||
</div>
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-3 overflow-auto">
|
||||
{batch?.combined && (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
export const LANE_ENGINES = ["session-dedup", "ccr", "lite", "rtk", "headroom", "caveman", "aggressive", "ultra"] as const;
|
||||
export interface PlaygroundInputProps { text: string; onText: (t: string) => void; active: string[]; onToggleActive: (engine: string) => void; onRun: () => void; loading: boolean; }
|
||||
export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, loading }: PlaygroundInputProps) {
|
||||
export interface PlaygroundInputProps { text: string; onText: (t: string) => void; active: string[]; onToggleActive: (engine: string) => void; onRun: () => void; loading: boolean; fidelityGate: boolean; onToggleFidelity: () => void; }
|
||||
export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, loading, fidelityGate, onToggleFidelity }: PlaygroundInputProps) {
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<textarea data-testid="play-input" className="min-h-[160px] w-full rounded border p-2 font-mono text-xs" value={text} onChange={(e) => onText(e.target.value)} placeholder="Cole prompt / tool-output / contexto..." />
|
||||
@@ -10,6 +10,10 @@ export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, l
|
||||
{LANE_ENGINES.map((e) => (<label key={e} className="flex items-center gap-2 text-sm"><input type="checkbox" checked={active.includes(e)} onChange={() => onToggleActive(e)} />{e}</label>))}
|
||||
<label className="flex items-center gap-2 text-sm opacity-50"><input type="checkbox" disabled /> llmlingua <span className="text-[10px]">(requer modelo ONNX)</span></label>
|
||||
</div>
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<input type="checkbox" data-testid="fidelity-toggle" checked={fidelityGate} onChange={onToggleFidelity} />
|
||||
Verificar fidelidade (rejeitar camada que corromper)
|
||||
</label>
|
||||
<button data-testid="play-run" className="rounded bg-blue-500/30 py-2 font-semibold" onClick={onRun} disabled={loading}>{loading ? "Rodando..." : "▶ Run"}</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -21,6 +21,8 @@ export interface CompressionEngineStep {
|
||||
techniquesUsed: string[];
|
||||
rulesApplied?: string[];
|
||||
durationMs?: number;
|
||||
rejected?: boolean;
|
||||
rejectReason?: string;
|
||||
}
|
||||
|
||||
// ── Diff ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -4,7 +4,7 @@ import { previewToRunModel, type CompressionRunModel, type PreviewResponse } fro
|
||||
export interface PreviewMessage { role: string; content: unknown; }
|
||||
export interface Lane { engine: string; run: CompressionRunModel | null; error: string | null; }
|
||||
export interface PreviewBatch { lanes: Lane[]; combined: CompressionRunModel | null; diff: PreviewResponse["diff"] | null; }
|
||||
export interface RunPreviewArgs { messages: PreviewMessage[]; laneEngines: string[]; activeEngines: string[]; language?: string; }
|
||||
export interface RunPreviewArgs { messages: PreviewMessage[]; laneEngines: string[]; activeEngines: string[]; language?: string; fidelityGate?: boolean; }
|
||||
async function postPreview(payload: Record<string, unknown>): Promise<PreviewResponse> {
|
||||
const res = await fetch("/api/compression/preview", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
|
||||
const data = await res.json();
|
||||
@@ -12,17 +12,17 @@ async function postPreview(payload: Record<string, unknown>): Promise<PreviewRes
|
||||
return data as PreviewResponse;
|
||||
}
|
||||
export async function runPreviewBatch(args: RunPreviewArgs): Promise<PreviewBatch> {
|
||||
const { messages, laneEngines, activeEngines } = args;
|
||||
const { messages, laneEngines, activeEngines, fidelityGate } = args;
|
||||
const lanes: Lane[] = await Promise.all(
|
||||
laneEngines.map(async (engine): Promise<Lane> => {
|
||||
try { const res = await postPreview({ messages, engineId: engine }); return { engine, run: previewToRunModel(res, engine), error: null }; }
|
||||
try { const res = await postPreview({ messages, engineId: engine, ...(fidelityGate ? { fidelityGate: { enabled: true } } : {}) }); return { engine, run: previewToRunModel(res, engine), error: null }; }
|
||||
catch (e) { return { engine, run: null, error: e instanceof Error ? e.message : "error" }; }
|
||||
})
|
||||
);
|
||||
let combined: CompressionRunModel | null = null;
|
||||
let diff: PreviewResponse["diff"] | null = null;
|
||||
if (activeEngines.length > 0) {
|
||||
try { const res = await postPreview({ messages, pipeline: activeEngines }); combined = previewToRunModel(res, activeEngines.join(" → ")); diff = res.diff; }
|
||||
try { const res = await postPreview({ messages, pipeline: activeEngines, ...(fidelityGate ? { fidelityGate: { enabled: true } } : {}) }); combined = previewToRunModel(res, activeEngines.join(" → ")); diff = res.diff; }
|
||||
catch { combined = null; }
|
||||
}
|
||||
return { lanes, combined, diff };
|
||||
|
||||
22
tests/unit/ui/fidelityGateToggle.test.tsx
Normal file
22
tests/unit/ui/fidelityGateToggle.test.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
// @vitest-environment jsdom
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { runPreviewBatch } from "@/hooks/usePreviewCompression";
|
||||
beforeEach(() => vi.restoreAllMocks());
|
||||
describe("runPreviewBatch fidelityGate", () => {
|
||||
it("includes fidelityGate:{enabled:true} in every preview payload when on", async () => {
|
||||
const payloads: any[] = [];
|
||||
vi.stubGlobal("fetch", vi.fn(async (_u: string, init: any) => {
|
||||
payloads.push(JSON.parse(init.body));
|
||||
return { ok: true, json: async () => ({
|
||||
original: "o", compressed: "c", originalTokens: 5, compressedTokens: 5, savingsPct: 0,
|
||||
mode: "stacked", durationMs: 1, engineBreakdown: [], diff: [], preservedBlocks: [], ruleRemovals: [],
|
||||
}) } as any;
|
||||
}));
|
||||
await runPreviewBatch({
|
||||
messages: [{ role: "user", content: "x" }],
|
||||
laneEngines: ["rtk"], activeEngines: ["rtk"], fidelityGate: true,
|
||||
});
|
||||
expect(payloads.length).toBe(2); // 1 lane + 1 combined
|
||||
expect(payloads.every((p) => p.fidelityGate?.enabled === true)).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user