system HF Staff commited on
Commit
91c64df
·
verified ·
1 Parent(s): 8253b03

Publish fashion-products bundle (Hyper3Labs/hyper3labs.github.io@25c2af8) from Hyper3Labs/hyperview-spaces@e95a262

Browse files
Dockerfile CHANGED
@@ -18,7 +18,7 @@ WORKDIR /home/user/app
18
  RUN pip install --upgrade pip
19
  RUN pip install \
20
  "hyperview==1.1.1" \
21
- "hyper-models[ml]==0.3.1"
22
 
23
  # The bundle is the unit of delivery: `hyperview serve --from` restores the
24
  # exported workspace, dataset, and layouts from it at startup.
 
18
  RUN pip install --upgrade pip
19
  RUN pip install \
20
  "hyperview==1.1.1" \
21
+ "hyper-models[ml]==0.3.2"
22
 
23
  # The bundle is the unit of delivery: `hyperview serve --from` restores the
24
  # exported workspace, dataset, and layouts from it at startup.
bundle/api/dataset.json CHANGED
@@ -211,7 +211,7 @@
211
  "layout_key": "hyper-models__hyper3-clip-v0_5__33d32a431c15__poincare_umap__2d_1a6bcbc4",
212
  "method": "umap",
213
  "modality": "image",
214
- "model_id": "hyper3-clip-v0.5",
215
  "params": {
216
  "metric": "cosine",
217
  "min_dist": 0.08,
@@ -243,7 +243,7 @@
243
  "layout_key": "hyper-models__hyper3-clip-v0_5__42052c955756__poincare_umap__2d_1a6bcbc4",
244
  "method": "umap",
245
  "modality": "multimodal",
246
- "model_id": "hyper3-clip-v0.5",
247
  "params": {
248
  "metric": "cosine",
249
  "min_dist": 0.08,
@@ -279,7 +279,7 @@
279
  "id": "representation:hyper-models__hyper3-clip-v0_5__33d32a431c15",
280
  "kind": "vector",
281
  "modality": "image",
282
- "model_id": "hyper3-clip-v0.5",
283
  "provider": "hyper-models",
284
  "shape": [
285
  513
@@ -309,7 +309,7 @@
309
  "id": "representation:hyper-models__hyper3-clip-v0_5__42052c955756",
310
  "kind": "vector",
311
  "modality": "multimodal",
312
- "model_id": "hyper3-clip-v0.5",
313
  "provider": "hyper-models",
314
  "shape": [
315
  513
@@ -338,7 +338,7 @@
338
  "dim": 513,
339
  "geometry": "hyperboloid",
340
  "modality": "image",
341
- "model_id": "hyper3-clip-v0.5",
342
  "params": {
343
  "curvature": 0.10000000085302468
344
  },
@@ -351,7 +351,7 @@
351
  "count": 741,
352
  "dim": 513,
353
  "geometry": "hyperboloid",
354
- "model_id": "hyper3-clip-v0.5",
355
  "provider": "hyper-models",
356
  "space_key": "hyper-models__hyper3-clip-v0_5__33d32a431c15"
357
  },
@@ -375,7 +375,7 @@
375
  "dim": 513,
376
  "geometry": "hyperboloid",
377
  "modality": "multimodal",
378
- "model_id": "hyper3-clip-v0.5",
379
  "params": {
380
  "curvature": 0.10000000091064717
381
  },
@@ -388,7 +388,7 @@
388
  "count": 741,
389
  "dim": 513,
390
  "geometry": "hyperboloid",
391
- "model_id": "hyper3-clip-v0.5",
392
  "provider": "hyper-models",
393
  "space_key": "hyper-models__hyper3-clip-v0_5__42052c955756"
394
  }
 
211
  "layout_key": "hyper-models__hyper3-clip-v0_5__33d32a431c15__poincare_umap__2d_1a6bcbc4",
212
  "method": "umap",
213
  "modality": "image",
214
+ "model_id": "hyper3-clip-v1",
215
  "params": {
216
  "metric": "cosine",
217
  "min_dist": 0.08,
 
243
  "layout_key": "hyper-models__hyper3-clip-v0_5__42052c955756__poincare_umap__2d_1a6bcbc4",
244
  "method": "umap",
245
  "modality": "multimodal",
246
+ "model_id": "hyper3-clip-v1",
247
  "params": {
248
  "metric": "cosine",
249
  "min_dist": 0.08,
 
279
  "id": "representation:hyper-models__hyper3-clip-v0_5__33d32a431c15",
280
  "kind": "vector",
281
  "modality": "image",
282
+ "model_id": "hyper3-clip-v1",
283
  "provider": "hyper-models",
284
  "shape": [
285
  513
 
309
  "id": "representation:hyper-models__hyper3-clip-v0_5__42052c955756",
310
  "kind": "vector",
311
  "modality": "multimodal",
312
+ "model_id": "hyper3-clip-v1",
313
  "provider": "hyper-models",
314
  "shape": [
315
  513
 
338
  "dim": 513,
339
  "geometry": "hyperboloid",
340
  "modality": "image",
341
+ "model_id": "hyper3-clip-v1",
342
  "params": {
343
  "curvature": 0.10000000085302468
344
  },
 
351
  "count": 741,
352
  "dim": 513,
353
  "geometry": "hyperboloid",
354
+ "model_id": "hyper3-clip-v1",
355
  "provider": "hyper-models",
356
  "space_key": "hyper-models__hyper3-clip-v0_5__33d32a431c15"
357
  },
 
375
  "dim": 513,
376
  "geometry": "hyperboloid",
377
  "modality": "multimodal",
378
+ "model_id": "hyper3-clip-v1",
379
  "params": {
380
  "curvature": 0.10000000091064717
381
  },
 
388
  "count": 741,
389
  "dim": 513,
390
  "geometry": "hyperboloid",
391
+ "model_id": "hyper3-clip-v1",
392
  "provider": "hyper-models",
393
  "space_key": "hyper-models__hyper3-clip-v0_5__42052c955756"
394
  }
bundle/api/panels/content/fashion-typed-search-business-evidence-v3/fashion-search-readout/panel.js CHANGED
@@ -68,5 +68,5 @@ export default function FashionSearchPanel() {
68
  const models = props.models || {};
69
  return /* @__PURE__ */ React.createElement(Panel, null, /* @__PURE__ */ React.createElement("div", { className: "fs-root" }, /* @__PURE__ */ React.createElement("style", null, `
70
  .fs-root,.fs-root *{box-sizing:border-box}.fs-root{flex:1;min-height:0;overflow:auto;padding:14px;background:var(--hv-color-background);color:var(--hv-color-foreground);font:11px/1.42 system-ui,-apple-system,BlinkMacSystemFont,sans-serif}.fs-kicker{display:block;color:var(--hv-color-muted-foreground);font-size:9px;font-weight:800;letter-spacing:.09em;text-transform:uppercase}.fs-header h2{margin:3px 0 0;font-size:18px;line-height:1.15;letter-spacing:-.02em}.fs-header p{margin:6px 0 0;color:var(--hv-color-muted-foreground)}.fs-tabs{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:11px}.fs-tab{border:1px solid var(--hv-color-border);border-radius:8px;padding:9px 8px;background:var(--hv-color-surface);color:var(--hv-color-muted-foreground);cursor:pointer;font-weight:760}.fs-tab:hover{border-color:color-mix(in srgb,var(--hv-color-accent) 55%,var(--hv-color-border));color:var(--hv-color-foreground)}.fs-tab.is-active{border-color:var(--hv-color-accent);background:color-mix(in srgb,var(--hv-color-accent) 20%,var(--hv-color-surface));color:var(--hv-color-foreground);box-shadow:inset 0 0 0 1px var(--hv-color-accent)}.fs-query{margin:10px 0 0;padding:8px 9px;border-left:2px solid var(--hv-color-accent);background:var(--hv-color-surface-muted);font-size:12px;font-weight:660}.fs-visual{display:grid;grid-template-columns:104px minmax(0,1fr);gap:9px;align-items:center;width:100%;margin-top:9px;border:1px solid var(--hv-color-border);border-radius:8px;padding:7px;background:var(--hv-color-surface);color:var(--hv-color-foreground);text-align:left;cursor:pointer}.fs-visual img{width:104px;height:96px;object-fit:contain;border-radius:5px;background:var(--hv-color-surface-muted)}.fs-visual strong,.fs-visual small{display:block}.fs-visual strong{margin-top:3px;font-size:12px}.fs-visual small{margin-top:3px;color:var(--hv-color-muted-foreground);font-size:9px}.fs-models{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:9px}.fs-model{border:1px solid var(--hv-color-border);border-radius:8px;padding:9px;background:var(--hv-color-surface)}.fs-model-top{display:flex;justify-content:space-between;gap:6px;font-weight:750}.fs-model-top span{display:flex;align-items:center;gap:5px}.fs-model-top i{width:7px;height:7px;border-radius:99px}.fs-model-top strong{font-size:17px}.fs-model>small{display:block;color:var(--hv-color-muted-foreground);font-size:8px}.fs-model p{margin:6px 0 0;color:var(--hv-color-muted-foreground);font-size:9px}.fs-cases{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:9px}.fs-case{border:1px solid var(--hv-color-border);border-radius:8px;padding:8px;background:var(--hv-color-surface);color:var(--hv-color-foreground);text-align:left;cursor:pointer}.fs-case:hover{border-color:color-mix(in srgb,var(--hv-color-accent) 55%,var(--hv-color-border))}.fs-case[aria-pressed=true]{border-color:var(--hv-color-accent);background:color-mix(in srgb,var(--hv-color-accent) 16%,var(--hv-color-surface));box-shadow:inset 0 0 0 1px var(--hv-color-accent)}.fs-case strong,.fs-case small{display:block}.fs-case small{margin-top:2px;color:var(--hv-color-muted-foreground);font-size:8px}.fs-benchmark{margin-top:13px;border-top:1px solid var(--hv-color-border);padding-top:10px}.fs-benchmark h3{margin:3px 0 2px;font-size:12px}.fs-caption{margin:0 0 7px;color:var(--hv-color-muted-foreground);font-size:9px}.fs-table{width:100%;border-collapse:collapse;font-size:9px}.fs-table th,.fs-table td{padding:5px 4px;border-bottom:1px solid var(--hv-color-border);text-align:right}.fs-table th:first-child,.fs-table td:first-child{text-align:left}.fs-table th{color:var(--hv-color-muted-foreground);font-size:8px;text-transform:uppercase}.fs-note{margin:7px 0 0;color:var(--hv-color-muted-foreground);font-size:9px}.fs-error{color:#ef4444}.fs-busy{opacity:.62}@media(max-width:390px){.fs-root{padding:10px}.fs-models{grid-template-columns:1fr}.fs-visual{grid-template-columns:82px minmax(0,1fr)}.fs-visual img{width:82px;height:78px}}
71
- `), /* @__PURE__ */ React.createElement("header", { className: "fs-header" }, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, "Catalog search"), /* @__PURE__ */ React.createElement("h2", null, mode === "photo" ? "Same product, another photo. Can search find it?" : `Does search find ${active.label.toLowerCase()}?`), /* @__PURE__ */ React.createElement("p", null, mode === "photo" ? "Use one product photo to find its other catalog views." : "Compare the same detailed request across both models.")), /* @__PURE__ */ React.createElement("nav", { className: "fs-tabs", "aria-label": "Search type" }, /* @__PURE__ */ React.createElement("button", { type: "button", className: `fs-tab${mode === "photo" ? " is-active" : ""}`, onClick: () => present(activePhoto, "photo") }, "Photo match"), /* @__PURE__ */ React.createElement("button", { type: "button", className: `fs-tab${mode === "text" ? " is-active" : ""}`, onClick: () => present(activeText, "text") }, "Typed search")), mode === "text" ? /* @__PURE__ */ React.createElement("blockquote", { className: "fs-query" }, "\u201C", active.query, "\u201D") : null, /* @__PURE__ */ React.createElement("button", { type: "button", className: "fs-visual", onClick: () => void setSelection([visualSampleId]) }, visualUrl ? /* @__PURE__ */ React.createElement("img", { src: visualUrl, alt: active.label }) : null, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, mode === "photo" ? "Starting photo" : "Matching product"), /* @__PURE__ */ React.createElement("strong", null, active.label), /* @__PURE__ */ React.createElement("small", null, mode === "photo" ? active.context : "Any view of this product counts as a match."), mode === "photo" ? /* @__PURE__ */ React.createElement("small", null, "Correct means the same product ID, not a similar style.") : null)), /* @__PURE__ */ React.createElement("section", { className: "fs-models", "aria-label": "First matching product rank" }, /* @__PURE__ */ React.createElement(ModelCard, { name: "Hyper3-CLIP", checkpoint: models.hyper3 || "v0.5", color: "#60a5fa", rank: active.target.hyper3Rank, readout: active.modelReadout.hyper3 }), /* @__PURE__ */ React.createElement(ModelCard, { name: "OpenAI CLIP", checkpoint: models.clip || "ViT-B/32", color: "#f59e0b", rank: active.target.clipRank, readout: active.modelReadout.clip })), mode === "photo" ? /* @__PURE__ */ React.createElement("nav", { className: "fs-cases", "aria-label": "Photo matching examples" }, photoCases.map((item) => /* @__PURE__ */ React.createElement("button", { key: item.id, type: "button", className: `fs-case${busy ? " fs-busy" : ""}`, "aria-pressed": item.id === active.id, disabled: busy, onClick: () => present(item, "photo") }, /* @__PURE__ */ React.createElement("strong", null, item.label), /* @__PURE__ */ React.createElement("small", null, item.context)))) : textCases.length > 1 ? /* @__PURE__ */ React.createElement("nav", { className: "fs-cases", "aria-label": "Typed search examples" }, textCases.map((item) => /* @__PURE__ */ React.createElement("button", { key: item.id, type: "button", className: `fs-case${busy ? " fs-busy" : ""}`, "aria-pressed": item.id === active.id, disabled: busy, onClick: () => present(item, "text") }, /* @__PURE__ */ React.createElement("strong", null, item.label), /* @__PURE__ */ React.createElement("small", null, item.target.hyper3Rank === 1 ? "Hyper3 first" : item.target.clipRank === 1 ? "CLIP first" : "Compare ranks")))) : null, /* @__PURE__ */ React.createElement("section", { className: "fs-benchmark", "aria-label": "Full benchmark results" }, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, "How the models compare"), mode === "photo" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h3", null, photoBenchmark.queryCount, " queries \xB7 ", photoBenchmark.candidateCount, " catalog photos"), /* @__PURE__ */ React.createElement("p", { className: "fs-caption" }, "Correct means another view of the same product."), /* @__PURE__ */ React.createElement("table", { className: "fs-table" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Correct product"), /* @__PURE__ */ React.createElement("th", { style: { color: "#60a5fa" } }, "Hyper3"), /* @__PURE__ */ React.createElement("th", { style: { color: "#f59e0b" } }, "CLIP"))), /* @__PURE__ */ React.createElement("tbody", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Ranked first"), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.hyper3R1)), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.clipR1))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top ten"), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.hyper3R10)), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.clipR10))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Mean average precision"), /* @__PURE__ */ React.createElement("td", null, Number(photoBenchmark.hyper3Map).toFixed(3)), /* @__PURE__ */ React.createElement("td", null, Number(photoBenchmark.clipMap).toFixed(3))))), /* @__PURE__ */ React.createElement("p", { className: "fs-note" }, "Cases use the largest first-match rank gap in each direction, so the CLIP win is shown too. Photo matching and typed retrieval are separate evaluations; their scores are not interchangeable.")) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h3", null, typed.queryCount, " written requests \xB7 ", typed.candidateCount, " photos"), /* @__PURE__ */ React.createElement("p", { className: "fs-caption" }, "Correct means any view of the described product."), /* @__PURE__ */ React.createElement("table", { className: "fs-table" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Correct product"), /* @__PURE__ */ React.createElement("th", { style: { color: "#60a5fa" } }, "Hyper3"), /* @__PURE__ */ React.createElement("th", { style: { color: "#f59e0b" } }, "CLIP"))), /* @__PURE__ */ React.createElement("tbody", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Ranked first"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit1)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit1))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top ten"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit10)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit10))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top fifty"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit50)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit50))))), /* @__PURE__ */ React.createElement("p", { className: "fs-note" }, "This is one illustrative Hyper3 win. Across the full 1,120-photo benchmark, the models are close and OpenAI CLIP is ahead at fifty results. The visible workspace map contains ", props.workspaceSampleCount || 741, " catalog photos."))), samplePage.error ? /* @__PURE__ */ React.createElement("p", { className: "fs-error" }, samplePage.error) : null, error ? /* @__PURE__ */ React.createElement("p", { className: "fs-error", role: "alert" }, error) : null));
72
  }
 
68
  const models = props.models || {};
69
  return /* @__PURE__ */ React.createElement(Panel, null, /* @__PURE__ */ React.createElement("div", { className: "fs-root" }, /* @__PURE__ */ React.createElement("style", null, `
70
  .fs-root,.fs-root *{box-sizing:border-box}.fs-root{flex:1;min-height:0;overflow:auto;padding:14px;background:var(--hv-color-background);color:var(--hv-color-foreground);font:11px/1.42 system-ui,-apple-system,BlinkMacSystemFont,sans-serif}.fs-kicker{display:block;color:var(--hv-color-muted-foreground);font-size:9px;font-weight:800;letter-spacing:.09em;text-transform:uppercase}.fs-header h2{margin:3px 0 0;font-size:18px;line-height:1.15;letter-spacing:-.02em}.fs-header p{margin:6px 0 0;color:var(--hv-color-muted-foreground)}.fs-tabs{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:11px}.fs-tab{border:1px solid var(--hv-color-border);border-radius:8px;padding:9px 8px;background:var(--hv-color-surface);color:var(--hv-color-muted-foreground);cursor:pointer;font-weight:760}.fs-tab:hover{border-color:color-mix(in srgb,var(--hv-color-accent) 55%,var(--hv-color-border));color:var(--hv-color-foreground)}.fs-tab.is-active{border-color:var(--hv-color-accent);background:color-mix(in srgb,var(--hv-color-accent) 20%,var(--hv-color-surface));color:var(--hv-color-foreground);box-shadow:inset 0 0 0 1px var(--hv-color-accent)}.fs-query{margin:10px 0 0;padding:8px 9px;border-left:2px solid var(--hv-color-accent);background:var(--hv-color-surface-muted);font-size:12px;font-weight:660}.fs-visual{display:grid;grid-template-columns:104px minmax(0,1fr);gap:9px;align-items:center;width:100%;margin-top:9px;border:1px solid var(--hv-color-border);border-radius:8px;padding:7px;background:var(--hv-color-surface);color:var(--hv-color-foreground);text-align:left;cursor:pointer}.fs-visual img{width:104px;height:96px;object-fit:contain;border-radius:5px;background:var(--hv-color-surface-muted)}.fs-visual strong,.fs-visual small{display:block}.fs-visual strong{margin-top:3px;font-size:12px}.fs-visual small{margin-top:3px;color:var(--hv-color-muted-foreground);font-size:9px}.fs-models{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:9px}.fs-model{border:1px solid var(--hv-color-border);border-radius:8px;padding:9px;background:var(--hv-color-surface)}.fs-model-top{display:flex;justify-content:space-between;gap:6px;font-weight:750}.fs-model-top span{display:flex;align-items:center;gap:5px}.fs-model-top i{width:7px;height:7px;border-radius:99px}.fs-model-top strong{font-size:17px}.fs-model>small{display:block;color:var(--hv-color-muted-foreground);font-size:8px}.fs-model p{margin:6px 0 0;color:var(--hv-color-muted-foreground);font-size:9px}.fs-cases{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:9px}.fs-case{border:1px solid var(--hv-color-border);border-radius:8px;padding:8px;background:var(--hv-color-surface);color:var(--hv-color-foreground);text-align:left;cursor:pointer}.fs-case:hover{border-color:color-mix(in srgb,var(--hv-color-accent) 55%,var(--hv-color-border))}.fs-case[aria-pressed=true]{border-color:var(--hv-color-accent);background:color-mix(in srgb,var(--hv-color-accent) 16%,var(--hv-color-surface));box-shadow:inset 0 0 0 1px var(--hv-color-accent)}.fs-case strong,.fs-case small{display:block}.fs-case small{margin-top:2px;color:var(--hv-color-muted-foreground);font-size:8px}.fs-benchmark{margin-top:13px;border-top:1px solid var(--hv-color-border);padding-top:10px}.fs-benchmark h3{margin:3px 0 2px;font-size:12px}.fs-caption{margin:0 0 7px;color:var(--hv-color-muted-foreground);font-size:9px}.fs-table{width:100%;border-collapse:collapse;font-size:9px}.fs-table th,.fs-table td{padding:5px 4px;border-bottom:1px solid var(--hv-color-border);text-align:right}.fs-table th:first-child,.fs-table td:first-child{text-align:left}.fs-table th{color:var(--hv-color-muted-foreground);font-size:8px;text-transform:uppercase}.fs-note{margin:7px 0 0;color:var(--hv-color-muted-foreground);font-size:9px}.fs-error{color:#ef4444}.fs-busy{opacity:.62}@media(max-width:390px){.fs-root{padding:10px}.fs-models{grid-template-columns:1fr}.fs-visual{grid-template-columns:82px minmax(0,1fr)}.fs-visual img{width:82px;height:78px}}
71
+ `), /* @__PURE__ */ React.createElement("header", { className: "fs-header" }, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, "Catalog search"), /* @__PURE__ */ React.createElement("h2", null, mode === "photo" ? "Same product, another photo. Can search find it?" : `Does search find ${active.label.toLowerCase()}?`), /* @__PURE__ */ React.createElement("p", null, mode === "photo" ? "Use one product photo to find its other catalog views." : "Compare the same detailed request across both models.")), /* @__PURE__ */ React.createElement("nav", { className: "fs-tabs", "aria-label": "Search type" }, /* @__PURE__ */ React.createElement("button", { type: "button", className: `fs-tab${mode === "photo" ? " is-active" : ""}`, onClick: () => present(activePhoto, "photo") }, "Photo match"), /* @__PURE__ */ React.createElement("button", { type: "button", className: `fs-tab${mode === "text" ? " is-active" : ""}`, onClick: () => present(activeText, "text") }, "Typed search")), mode === "text" ? /* @__PURE__ */ React.createElement("blockquote", { className: "fs-query" }, "\u201C", active.query, "\u201D") : null, /* @__PURE__ */ React.createElement("button", { type: "button", className: "fs-visual", onClick: () => void setSelection([visualSampleId]) }, visualUrl ? /* @__PURE__ */ React.createElement("img", { src: visualUrl, alt: active.label }) : null, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, mode === "photo" ? "Starting photo" : "Matching product"), /* @__PURE__ */ React.createElement("strong", null, active.label), /* @__PURE__ */ React.createElement("small", null, mode === "photo" ? active.context : "Any view of this product counts as a match."), mode === "photo" ? /* @__PURE__ */ React.createElement("small", null, "Correct means the same product ID, not a similar style.") : null)), /* @__PURE__ */ React.createElement("section", { className: "fs-models", "aria-label": "First matching product rank" }, /* @__PURE__ */ React.createElement(ModelCard, { name: "Hyper3-CLIP", checkpoint: models.hyper3 || "v1", color: "#60a5fa", rank: active.target.hyper3Rank, readout: active.modelReadout.hyper3 }), /* @__PURE__ */ React.createElement(ModelCard, { name: "OpenAI CLIP", checkpoint: models.clip || "ViT-B/32", color: "#f59e0b", rank: active.target.clipRank, readout: active.modelReadout.clip })), mode === "photo" ? /* @__PURE__ */ React.createElement("nav", { className: "fs-cases", "aria-label": "Photo matching examples" }, photoCases.map((item) => /* @__PURE__ */ React.createElement("button", { key: item.id, type: "button", className: `fs-case${busy ? " fs-busy" : ""}`, "aria-pressed": item.id === active.id, disabled: busy, onClick: () => present(item, "photo") }, /* @__PURE__ */ React.createElement("strong", null, item.label), /* @__PURE__ */ React.createElement("small", null, item.context)))) : textCases.length > 1 ? /* @__PURE__ */ React.createElement("nav", { className: "fs-cases", "aria-label": "Typed search examples" }, textCases.map((item) => /* @__PURE__ */ React.createElement("button", { key: item.id, type: "button", className: `fs-case${busy ? " fs-busy" : ""}`, "aria-pressed": item.id === active.id, disabled: busy, onClick: () => present(item, "text") }, /* @__PURE__ */ React.createElement("strong", null, item.label), /* @__PURE__ */ React.createElement("small", null, item.target.hyper3Rank === 1 ? "Hyper3 first" : item.target.clipRank === 1 ? "CLIP first" : "Compare ranks")))) : null, /* @__PURE__ */ React.createElement("section", { className: "fs-benchmark", "aria-label": "Full benchmark results" }, /* @__PURE__ */ React.createElement("span", { className: "fs-kicker" }, "How the models compare"), mode === "photo" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h3", null, photoBenchmark.queryCount, " queries \xB7 ", photoBenchmark.candidateCount, " catalog photos"), /* @__PURE__ */ React.createElement("p", { className: "fs-caption" }, "Correct means another view of the same product."), /* @__PURE__ */ React.createElement("table", { className: "fs-table" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Correct product"), /* @__PURE__ */ React.createElement("th", { style: { color: "#60a5fa" } }, "Hyper3"), /* @__PURE__ */ React.createElement("th", { style: { color: "#f59e0b" } }, "CLIP"))), /* @__PURE__ */ React.createElement("tbody", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Ranked first"), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.hyper3R1)), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.clipR1))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top ten"), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.hyper3R10)), /* @__PURE__ */ React.createElement("td", null, percentage(photoBenchmark.clipR10))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Mean average precision"), /* @__PURE__ */ React.createElement("td", null, Number(photoBenchmark.hyper3Map).toFixed(3)), /* @__PURE__ */ React.createElement("td", null, Number(photoBenchmark.clipMap).toFixed(3))))), /* @__PURE__ */ React.createElement("p", { className: "fs-note" }, "Cases use the largest first-match rank gap in each direction, so the CLIP win is shown too. Photo matching and typed retrieval are separate evaluations; their scores are not interchangeable.")) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h3", null, typed.queryCount, " written requests \xB7 ", typed.candidateCount, " photos"), /* @__PURE__ */ React.createElement("p", { className: "fs-caption" }, "Correct means any view of the described product."), /* @__PURE__ */ React.createElement("table", { className: "fs-table" }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Correct product"), /* @__PURE__ */ React.createElement("th", { style: { color: "#60a5fa" } }, "Hyper3"), /* @__PURE__ */ React.createElement("th", { style: { color: "#f59e0b" } }, "CLIP"))), /* @__PURE__ */ React.createElement("tbody", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Ranked first"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit1)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit1))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top ten"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit10)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit10))), /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("td", null, "Within top fifty"), /* @__PURE__ */ React.createElement("td", null, percentage(typed.hyper3Hit50)), /* @__PURE__ */ React.createElement("td", null, percentage(typed.clipHit50))))), /* @__PURE__ */ React.createElement("p", { className: "fs-note" }, "This is one illustrative Hyper3 win. Across the full 1,120-photo benchmark, the models are close and OpenAI CLIP is ahead at fifty results. The visible workspace map contains ", props.workspaceSampleCount || 741, " catalog photos."))), samplePage.error ? /* @__PURE__ */ React.createElement("p", { className: "fs-error" }, samplePage.error) : null, error ? /* @__PURE__ */ React.createElement("p", { className: "fs-error", role: "alert" }, error) : null));
72
  }
bundle/api/runtime.json CHANGED
@@ -726,7 +726,7 @@
726
  "initialTextCaseId": "light-denim-leggings",
727
  "models": {
728
  "clip": "OpenAI CLIP ViT-B/32",
729
- "hyper3": "Hyper3-CLIP v0.5"
730
  },
731
  "photoArtifact": {
732
  "hashProjection": "canonical JSON of {photoBenchmark, photoCases}",
 
726
  "initialTextCaseId": "light-denim-leggings",
727
  "models": {
728
  "clip": "OpenAI CLIP ViT-B/32",
729
+ "hyper3": "Hyper3-CLIP v1"
730
  },
731
  "photoArtifact": {
732
  "hashProjection": "canonical JSON of {photoBenchmark, photoCases}",