Skip to content

Commit 2bbfb9e

Browse files
committed
feat(site): any-to-any ingress/egress dropdowns on the Translation tab
Pinning the ingress to OpenAI was not principled: it privileged OpenAI-native gateways and the "fastest egress per gateway" default silently mixed egress dialects in one column. Instead, two dropdowns pin BOTH ends of the translation path, so the whole table ranks the identical <in>-><out> pair (truly apples-to-apples); a gateway that does not serve that pair is simply absent. - state.xlateIn/xlateOut (default openai->anthropic, the fullest-served pair), carried in the URL as xin/xout for shareable links. - Translation columns read the pinned matrix cell (xlateMatrixCell); the row set is the gateways serving that exact pair (servesXlatePair). Path pill dropped (the dropdowns are the path). Caption states the pinned pair. - Full in x out exploration stays; the Matrix tab remains the pass/fail grid, this tab is the ranked leaderboard for a chosen cell. 20 tests pass.
1 parent 824bfe1 commit 2bbfb9e

4 files changed

Lines changed: 91 additions & 33 deletions

File tree

‎site/app.js‎

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,27 @@ function servesOpenaiPassthrough(g) {
151151
return !!(cell && cell.served === true);
152152
}
153153

154-
/* xlateCell: the Translation tab reads the openai-in -> best non-openai egress cell (g.translation_cell,
155-
chosen by gen-data on lowest added latency, fixed fair ingress). Absent a matrix, fall back to the
156-
legacy xlate suite (anthropic-in / openai-out). Keys are cell.perf keys (added_latency_p99_us, ...). */
154+
/* xlateMatrixCell: the perf object for a gateway's ingress->egress translation cell, straight from the
155+
matrix (upstreams[egress].cells[ingress]). Returns cell.perf when that exact pair is served and
156+
measured, else null. The Translation tab pins BOTH ends (state.xlateIn/xlateOut) so every row is the
157+
identical translation and the ranking is apples-to-apples. */
158+
function xlateMatrixCell(g, ingress, egress) {
159+
const up = g.matrix && g.matrix.upstreams && g.matrix.upstreams[egress];
160+
const cell = up && up.cells && up.cells[ingress];
161+
return (cell && cell.served === true && cell.perf) ? cell.perf : null;
162+
}
163+
/* Does the gateway serve the pinned translation pair at all (green cell), measured or not? Drives the
164+
Translation tab's row set: only gateways that serve this exact ingress->egress path appear. */
165+
function servesXlatePair(g, ingress, egress) {
166+
const up = g.matrix && g.matrix.upstreams && g.matrix.upstreams[egress];
167+
const cell = up && up.cells && up.cells[ingress];
168+
return !!(cell && cell.served === true);
169+
}
170+
/* Column reader for the Translation tab: the pinned-pair cell's metric, n/a when the pair is served
171+
but unmeasured (perf sweep did not land). */
157172
function xlateCell(g, key, fmt) {
158-
if (g.translation_cell && g.translation_cell[key] != null)
159-
return { v: g.translation_cell[key], text: fmt(g.translation_cell[key]), na: false };
160-
if (!g.matrix || !g.matrix.upstreams) {
161-
const legacy = { added_latency_p99_us: "xlate_added_latency_p99_us", rps_sustained_20ms: "xlate_rps_sustained_20ms" }[key] || key;
162-
return lane(g, "xlate", "xlate_served", "xlate_error", (j) =>
163-
j[legacy] != null ? { v: j[legacy], text: fmt(j[legacy]), na: false } : { v: null, text: "n/a", na: true });
164-
}
173+
const perf = xlateMatrixCell(g, state.xlateIn, state.xlateOut);
174+
if (perf && perf[key] != null) return { v: perf[key], text: fmt(perf[key]), na: false };
165175
return { v: null, text: "n/a", na: true };
166176
}
167177

@@ -215,18 +225,14 @@ const COLUMN_SETS = {
215225
{ id: "mempeak", label: "Mem peak (MiB)", desc: false, title: "Peak process RSS under large-payload load",
216226
get: (g) => lane(g, "memory", "served", "serve_error", (j) => ({ v: j.peak_rss_mib, text: fmt1(j.peak_rss_mib), na: false })) },
217227
],
218-
// Translation: openai-in -> best non-openai egress. A path pill shows which egress this row's
219-
// number is; only gateways that actually translate appear (view-implicit filter).
228+
// Translation: the pinned ingress->egress pair (state.xlateIn/xlateOut), chosen by the two
229+
// dropdowns above the table. Every row is the identical translation; the path is the dropdowns,
230+
// so there is no per-row Path pill. Only gateways serving this exact pair appear.
220231
translation: [
221232
COL_SEL, COL_NAME, COL_LANG,
222-
{ id: "xlpath", label: "Path", desc: false, title: "OpenAI ingress translated to this egress dialect - the fastest translation path this gateway serves (chosen by lowest added latency)",
223-
get: (g) => ({ v: g.translation_cell ? g.translation_cell.egress : "", text: null, na: !g.translation_cell }),
224-
render: (g) => g.translation_cell
225-
? `<td class="tested"><span class="tested-pill" title="OpenAI ingress translated to ${esc(g.translation_cell.egress)} upstream">openai&nbsp;&rarr;&nbsp;${esc(g.translation_cell.egress)}</span></td>`
226-
: `<td class="tested"><span class="muted">n/a</span></td>` },
227-
{ id: "xllat", label: "Added latency p99 (µs)", desc: false, title: "Gateway p99 minus direct-to-mock p99 on the OpenAI-in translation path",
233+
{ id: "xllat", label: "Added latency p99 (µs)", desc: false, title: "Gateway p99 minus direct-to-mock p99 on the selected translation path",
228234
get: (g) => xlateCell(g, "added_latency_p99_us", fmtAdded) },
229-
{ id: "xlrps", label: "Sustained RPS @20ms", desc: true, title: "Sustained RPS @20ms on the OpenAI-in translation path (p99 < 1 s, <0.1% errors)",
235+
{ id: "xlrps", label: "Sustained RPS @20ms", desc: true, title: "Sustained RPS @20ms on the selected translation path (p99 < 1 s, <0.1% errors)",
230236
get: (g) => xlateCell(g, "rps_sustained_20ms", fmtInt) },
231237
],
232238
// Streaming: SSE passthrough, its own stall-gated ceiling.
@@ -297,6 +303,11 @@ function newState() {
297303
classes: new Set(),
298304
needStream: false,
299305
needXlate: false,
306+
// Translation tab: the pinned ingress->egress pair the whole table is ranked on. Both ends are
307+
// fixed so every row does the identical translation (apples-to-apples); a gateway that does not
308+
// serve this exact pair is absent. Default is the fullest-served pair.
309+
xlateIn: "openai",
310+
xlateOut: "anthropic",
300311
cmp: [], /* gateway keys selected for compare, max 3 */
301312
cmpOpen: false, /* compare panel visible */
302313
drawer: null, /* gateway key open in the drawer */
@@ -331,6 +342,9 @@ function encodeUrl(st) {
331342
if (st.cmp.length) p.set("cmp", st.cmp.join("|"));
332343
if (st.cmpOpen) p.set("cv", "1");
333344
if (st.drawer) p.set("gw", st.drawer);
345+
// Carry a non-default translation pair so a shared link opens the same ranking.
346+
if (st.xlateIn !== "openai") p.set("xin", st.xlateIn);
347+
if (st.xlateOut !== "anthropic") p.set("xout", st.xlateOut);
334348
const cat = CATEGORIES[st.category] ? st.category : DEFAULT_CATEGORY;
335349
const path = st.view && st.view !== "passthrough" ? `/${cat}/${st.view}` : `/${cat}`;
336350
const qs = p.toString();
@@ -378,6 +392,8 @@ function decodeUrl(pathname, search, hash) {
378392
st.cmp = list("cmp").slice(0, 3);
379393
st.cmpOpen = p.get("cv") === "1" && st.cmp.length >= 2;
380394
st.drawer = p.get("gw") || null;
395+
if (MATRIX_CELLS.includes(p.get("xin"))) st.xlateIn = p.get("xin");
396+
if (MATRIX_CELLS.includes(p.get("xout"))) st.xlateOut = p.get("xout");
381397
return st;
382398
}
383399

@@ -413,10 +429,10 @@ function applyFilters(gateways, st) {
413429
if (st.langs.size && !st.langs.has(g.lang)) return false;
414430
if (st.needStream && !(g.stream && g.stream.stream_served)) return false;
415431
if (st.needXlate && !hasTranslation(g)) return false;
416-
// View-implicit filter: the Translation tab lists only gateways that actually translate, the
417-
// Streaming tab only ones that serve SSE. A pure proxy that never translates simply is not in
418-
// the translation ranking (rather than sitting there as a row of n/a).
419-
if (st.view === "translation" && !hasTranslation(g)) return false;
432+
// View-implicit filter: the Translation tab lists only gateways that serve the pinned
433+
// ingress->egress pair (so every row is the identical translation); the Streaming tab only ones
434+
// that serve SSE. A gateway absent from a pair simply does not serve it.
435+
if (st.view === "translation" && !servesXlatePair(g, st.xlateIn, st.xlateOut)) return false;
420436
if (st.view === "streaming" && !(g.stream && g.stream.stream_served)) return false;
421437
return true;
422438
});
@@ -597,12 +613,18 @@ function initThemeToggle() {
597613
has to guess what the ranking compares. No em dashes (house style). */
598614
const TABLE_CAPTIONS = {
599615
passthrough: "OpenAI ingress to OpenAI upstream: pure passthrough, no translation. Every gateway runs the identical dialect, so the ranking is apples-to-apples. A gateway that does not serve OpenAI ingress reads n/a.",
600-
translation: "OpenAI ingress translated to another dialect. Each gateway is shown on the fastest translation path it serves (the Path pill). Only gateways that actually translate appear here.",
601616
streaming: "Server-sent-event passthrough. Streams sustained is each gateway's stall-free concurrent-stream ceiling; added TTFT and per-token are gateway minus direct-to-mock.",
602617
};
603618
function updateTableCaption(view) {
604619
const el = document.getElementById("table-caption");
605-
if (el) el.textContent = TABLE_CAPTIONS[view] || TABLE_CAPTIONS.passthrough;
620+
if (!el) return;
621+
if (view === "translation") {
622+
const inL = (MATRIX_LABELS[state.xlateIn] || state.xlateIn);
623+
const outL = (MATRIX_LABELS[state.xlateOut] || state.xlateOut);
624+
el.textContent = `Client speaks ${inL}, upstream speaks ${outL}: the gateway translates every request and response on this exact path. Only gateways that serve this pair appear, and every row is the identical translation, so the ranking is apples-to-apples.`;
625+
return;
626+
}
627+
el.textContent = TABLE_CAPTIONS[view] || TABLE_CAPTIONS.passthrough;
606628
}
607629
function renderTable() {
608630
const { data } = state;
@@ -706,6 +728,16 @@ function initFilterControls() {
706728
const el = document.getElementById(`f-${name}`);
707729
if (el) el.addEventListener("change", () => { state[key] = el.checked; renderTable(); syncUrl(true); });
708730
}
731+
// Translation ingress/egress pickers: populate the six dialects and re-rank on change.
732+
const xin = document.getElementById("xlate-in");
733+
const xout = document.getElementById("xlate-out");
734+
if (xin && xout) {
735+
const opts = MATRIX_CELLS.map((d) => `<option value="${esc(d)}">${esc(MATRIX_LABELS[d] || d)}</option>`).join("");
736+
xin.innerHTML = opts; xout.innerHTML = opts;
737+
const onPick = () => { state.xlateIn = xin.value; state.xlateOut = xout.value; renderTable(); syncUrl(true); };
738+
xin.addEventListener("change", onPick);
739+
xout.addEventListener("change", onPick);
740+
}
709741
}
710742

711743
function renderFilters() {
@@ -715,6 +747,8 @@ function renderFilters() {
715747
(l) => LANG_COLORS[l] || LANG_COLORS.Other);
716748
document.getElementById("search").value = state.q;
717749
for (const [, name] of CAPS) { const el = document.getElementById(`f-${name}`); if (el) el.checked = state[CAPS.find(([, n]) => n === name)[0]]; }
750+
const xin = document.getElementById("xlate-in"); if (xin) xin.value = state.xlateIn;
751+
const xout = document.getElementById("xlate-out"); if (xout) xout.value = state.xlateOut;
718752
}
719753

720754
/* ---- per-gateway drawer ----------------------------------------------------- */
@@ -1148,6 +1182,9 @@ function showView(view) {
11481182
x.setAttribute("href", viewPath(state.category, x.dataset.view));
11491183
});
11501184
document.querySelectorAll(".view").forEach((v) => v.classList.toggle("hidden", v.id !== containerId));
1185+
// The translation ingress/egress pickers only make sense on the Translation tab.
1186+
const picker = document.getElementById("xlate-picker");
1187+
if (picker) picker.classList.toggle("hidden", view !== "translation");
11511188
// Switching between perf tabs changes columns/caption/filtering, so re-render the table.
11521189
if (PERF_VIEWS.has(view) && state.data) renderTable();
11531190
updateTitle();
@@ -1166,6 +1203,7 @@ function applyState(st) {
11661203
category: st.category, view: st.view, q: st.q, sortCol: st.sortCol, sortDesc: st.sortDesc,
11671204
langs: st.langs, classes: st.classes,
11681205
needStream: st.needStream, needXlate: st.needXlate,
1206+
xlateIn: st.xlateIn, xlateOut: st.xlateOut,
11691207
cmp: st.cmp, cmpOpen: st.cmpOpen, drawer: st.drawer,
11701208
});
11711209
}

‎site/index.html‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ <h1>On the Bench <span class="brand-sub">AI tool benchmarks</span></h1>
6363
<input type="search" id="search" placeholder="Search gateways" aria-label="Search gateways by name">
6464
<div class="control-group" id="class-filters" aria-label="Filter by class (each project's own self-description)"></div>
6565
<div class="control-group" id="lang-filters" aria-label="Filter by language"></div>
66+
<div class="control-group xlate-picker hidden" id="xlate-picker">
67+
<label>Translate <select id="xlate-in" aria-label="Ingress dialect the client speaks"></select>
68+
<span class="xlate-arrow">&rarr;</span>
69+
<select id="xlate-out" aria-label="Egress dialect the upstream speaks"></select></label>
70+
</div>
6671
<span id="row-count" class="muted count"></span>
6772
</div>
6873
<p id="table-caption" class="fineprint"></p>

‎site/style.css‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,14 @@ tbody tr { cursor: pointer; }
318318
white-space: nowrap; font-variant: small-caps; letter-spacing: .02em;
319319
}
320320

321+
/* Translation ingress/egress picker (Translation tab only) */
322+
.xlate-picker label { display: inline-flex; align-items: center; gap: .4rem; color: var(--fg-dim); font-size: .85rem; }
323+
.xlate-picker select {
324+
background: var(--bg-raise); color: var(--fg); border: 1px solid var(--border);
325+
border-radius: 6px; padding: .25rem .5rem; font-size: .85rem; font-family: inherit;
326+
}
327+
.xlate-picker .xlate-arrow { color: var(--fg-mute); }
328+
321329
/* Floating hover popup for matrix cells: a small card that follows the hovered cell. */
322330
.matrix-pop {
323331
position: absolute; z-index: 50; max-width: 22rem; pointer-events: none;

‎site/test.mjs‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,22 @@ test("Passthrough reads the openai diagonal, n/a when openai is not_configurable
184184
assert.equal(app.passCell(native, "rps_sustained_20ms", String).na, true);
185185
});
186186

187-
test("Translation tab lists only gateways that translate", () => {
188-
const translator = { translation_cell: { egress: "anthropic", rps_sustained_20ms: 100 } };
189-
const proxy = { matrix: mkMatrix({ openai: { openai: { served: true } } }) }; // no translation cell
190-
assert.equal(app.hasTranslation(translator), true);
191-
assert.equal(app.hasTranslation(proxy), false);
187+
test("Translation tab lists only gateways serving the pinned in->out pair", () => {
188+
// g0 serves openai->anthropic (the default pair), g1 serves only openai->gemini.
189+
const g0 = { display: "g0", key: "g0", lang: "Rust",
190+
matrix: mkMatrix({ anthropic: { openai: { served: true, perf: { rps_sustained_20ms: 100, added_latency_p99_us: 200 } } } }) };
191+
const g1 = { display: "g1", key: "g1", lang: "Go",
192+
matrix: mkMatrix({ gemini: { openai: { served: true, perf: { rps_sustained_20ms: 90, added_latency_p99_us: 300 } } } }) };
192193
const st = app.newState();
193-
st.view = "translation";
194-
const rows = app.applyFilters([translator, proxy].map((g, i) => ({ display: "g" + i, key: "g" + i, lang: "Rust", ...g })), st);
195-
assert.deepEqual(rows.map((g) => g.key), ["g0"]);
194+
st.view = "translation"; // default pair openai -> anthropic
195+
assert.deepEqual(app.applyFilters([g0, g1], st).map((g) => g.key), ["g0"]);
196+
// repin to openai -> gemini and the row set follows the pair
197+
st.xlateOut = "gemini";
198+
assert.deepEqual(app.applyFilters([g0, g1], st).map((g) => g.key), ["g1"]);
199+
// the cell reader returns the pinned pair's perf
200+
st.xlateOut = "anthropic";
201+
assert.equal(app.xlateCell(g0, "rps_sustained_20ms", String).text, "100");
202+
assert.equal(app.xlateCell(g0, "rps_sustained_20ms", String).na, false);
196203
});
197204

198205
// ---- footer timestamps: clean UTC stamp + coarse relative age ----------------

0 commit comments

Comments
 (0)