Show samples alongside DeepFashion search demo
Browse files- .hyperview/extensions/fashion-search-readout/panel.js +32 -37
- Dockerfile +1 -1
- demo.py +25 -28
.hyperview/extensions/fashion-search-readout/panel.js
CHANGED
|
@@ -60,17 +60,14 @@ function TextBlock({ children }) {
|
|
| 60 |
|
| 61 |
function normalizeModels(value) {
|
| 62 |
if (!Array.isArray(value)) return [];
|
| 63 |
-
return value
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
buttonLabel
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
spaceKey: model.spaceKey || model.space_key || null,
|
| 72 |
-
}))
|
| 73 |
-
.filter((model) => model.layoutKey);
|
| 74 |
}
|
| 75 |
|
| 76 |
function getSummary(item, modelKey) {
|
|
@@ -348,7 +345,7 @@ function SearchResultComparison({ item, models, loadingKey, onSelectResult }) {
|
|
| 348 |
React.createElement(
|
| 349 |
"div",
|
| 350 |
{ style: { color: colors.mutedText, fontSize: 10, marginTop: 3 } },
|
| 351 |
-
"Green card = exact product.
|
| 352 |
),
|
| 353 |
),
|
| 354 |
models.map((model) =>
|
|
@@ -609,6 +606,7 @@ export default function FashionSearchComparisonPanel() {
|
|
| 609 |
const mode = panelProps.mode === "summary" ? "summary" : panelProps.mode === "results" ? "results" : "full";
|
| 610 |
|
| 611 |
const models = React.useMemo(() => normalizeModels(panelProps.models), [panelProps.models]);
|
|
|
|
| 612 |
const examples = Array.isArray(panelProps.examples) ? panelProps.examples : [];
|
| 613 |
const warnings = Array.isArray(panelProps.warnings) ? panelProps.warnings.filter(Boolean) : [];
|
| 614 |
const metrics = panelProps.metrics || {};
|
|
@@ -651,7 +649,6 @@ export default function FashionSearchComparisonPanel() {
|
|
| 651 |
const timer = window.setTimeout(() => {
|
| 652 |
[
|
| 653 |
"explorer",
|
| 654 |
-
"grid",
|
| 655 |
"scatter-euclidean",
|
| 656 |
"scatter-poincare",
|
| 657 |
"scatter-spherical",
|
|
@@ -665,7 +662,6 @@ export default function FashionSearchComparisonPanel() {
|
|
| 665 |
// Older HyperView builds may not have every panel id; ignore missing panes.
|
| 666 |
}
|
| 667 |
});
|
| 668 |
-
commands.focusPanel?.("fashion-buyer-readout");
|
| 669 |
commands.focusPanel?.("fashion-ranked-results");
|
| 670 |
}, 350);
|
| 671 |
|
|
@@ -683,7 +679,8 @@ export default function FashionSearchComparisonPanel() {
|
|
| 683 |
const key = `${item.queryId}:${model.key}`;
|
| 684 |
setPanelError(null);
|
| 685 |
if (!model.layoutKey) {
|
| 686 |
-
|
|
|
|
| 687 |
return;
|
| 688 |
}
|
| 689 |
setLoadingKey(key);
|
|
@@ -692,7 +689,6 @@ export default function FashionSearchComparisonPanel() {
|
|
| 692 |
await commands.showSimilar({
|
| 693 |
sampleId: item.queryId,
|
| 694 |
layoutKey: model.layoutKey,
|
| 695 |
-
spaceKey: model.spaceKey,
|
| 696 |
k: 10,
|
| 697 |
source: `fashion-demo:${model.key}`,
|
| 698 |
focus: false,
|
|
@@ -711,7 +707,11 @@ export default function FashionSearchComparisonPanel() {
|
|
| 711 |
const key = `${result.sampleId}:${model.key}:ranked-result`;
|
| 712 |
setPanelError(null);
|
| 713 |
if (!model.layoutKey) {
|
| 714 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 715 |
return;
|
| 716 |
}
|
| 717 |
setLoadingKey(key);
|
|
@@ -720,7 +720,6 @@ export default function FashionSearchComparisonPanel() {
|
|
| 720 |
await commands.showSimilar({
|
| 721 |
sampleId: result.sampleId,
|
| 722 |
layoutKey: model.layoutKey,
|
| 723 |
-
spaceKey: model.spaceKey,
|
| 724 |
k: 10,
|
| 725 |
source: `fashion-ranked-result:${model.key}`,
|
| 726 |
focus: false,
|
|
@@ -766,7 +765,7 @@ export default function FashionSearchComparisonPanel() {
|
|
| 766 |
React.createElement(
|
| 767 |
TextBlock,
|
| 768 |
null,
|
| 769 |
-
"Business readout for the selected shopper query.
|
| 770 |
),
|
| 771 |
examples.length
|
| 772 |
? React.createElement(ExampleChooser, {
|
|
@@ -843,27 +842,23 @@ export default function FashionSearchComparisonPanel() {
|
|
| 843 |
})
|
| 844 |
: null,
|
| 845 |
),
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
item: selectedExample,
|
| 857 |
-
models,
|
| 858 |
loadingKey,
|
| 859 |
onSelectQuery: selectModelQuery,
|
| 860 |
-
})
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
{ style: { color: colors.bodyText, fontSize: 12, lineHeight: 1.45 } },
|
| 864 |
-
"Demo examples are not configured.",
|
| 865 |
-
),
|
| 866 |
-
),
|
| 867 |
warnings.length
|
| 868 |
? React.createElement(
|
| 869 |
"div",
|
|
|
|
| 60 |
|
| 61 |
function normalizeModels(value) {
|
| 62 |
if (!Array.isArray(value)) return [];
|
| 63 |
+
return value.map((model, index) => ({
|
| 64 |
+
key: String(model.key || `model-${index}`),
|
| 65 |
+
displayName: String(model.displayName || model.display_name || model.key || `Model ${index + 1}`),
|
| 66 |
+
buttonLabel: String(
|
| 67 |
+
model.buttonLabel || model.button_label || `${model.displayName || model.key || "Model"} query`,
|
| 68 |
+
),
|
| 69 |
+
layoutKey: model.layoutKey || model.layout_key || null,
|
| 70 |
+
}));
|
|
|
|
|
|
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
function getSummary(item, modelKey) {
|
|
|
|
| 345 |
React.createElement(
|
| 346 |
"div",
|
| 347 |
{ style: { color: colors.mutedText, fontSize: 10, marginTop: 3 } },
|
| 348 |
+
"Green card = exact product. Click any card to select it in Samples.",
|
| 349 |
),
|
| 350 |
),
|
| 351 |
models.map((model) =>
|
|
|
|
| 606 |
const mode = panelProps.mode === "summary" ? "summary" : panelProps.mode === "results" ? "results" : "full";
|
| 607 |
|
| 608 |
const models = React.useMemo(() => normalizeModels(panelProps.models), [panelProps.models]);
|
| 609 |
+
const inspectableModels = React.useMemo(() => models.filter((model) => model.layoutKey), [models]);
|
| 610 |
const examples = Array.isArray(panelProps.examples) ? panelProps.examples : [];
|
| 611 |
const warnings = Array.isArray(panelProps.warnings) ? panelProps.warnings.filter(Boolean) : [];
|
| 612 |
const metrics = panelProps.metrics || {};
|
|
|
|
| 649 |
const timer = window.setTimeout(() => {
|
| 650 |
[
|
| 651 |
"explorer",
|
|
|
|
| 652 |
"scatter-euclidean",
|
| 653 |
"scatter-poincare",
|
| 654 |
"scatter-spherical",
|
|
|
|
| 662 |
// Older HyperView builds may not have every panel id; ignore missing panes.
|
| 663 |
}
|
| 664 |
});
|
|
|
|
| 665 |
commands.focusPanel?.("fashion-ranked-results");
|
| 666 |
}, 350);
|
| 667 |
|
|
|
|
| 679 |
const key = `${item.queryId}:${model.key}`;
|
| 680 |
setPanelError(null);
|
| 681 |
if (!model.layoutKey) {
|
| 682 |
+
await commands.setSelection?.([item.queryId], { persist: false, source: `fashion-target:${model.key}` });
|
| 683 |
+
commands.focusPanel?.("grid");
|
| 684 |
return;
|
| 685 |
}
|
| 686 |
setLoadingKey(key);
|
|
|
|
| 689 |
await commands.showSimilar({
|
| 690 |
sampleId: item.queryId,
|
| 691 |
layoutKey: model.layoutKey,
|
|
|
|
| 692 |
k: 10,
|
| 693 |
source: `fashion-demo:${model.key}`,
|
| 694 |
focus: false,
|
|
|
|
| 707 |
const key = `${result.sampleId}:${model.key}:ranked-result`;
|
| 708 |
setPanelError(null);
|
| 709 |
if (!model.layoutKey) {
|
| 710 |
+
await commands.setSelection?.([result.sampleId], {
|
| 711 |
+
persist: false,
|
| 712 |
+
source: `fashion-ranked-result:${model.key}`,
|
| 713 |
+
});
|
| 714 |
+
commands.focusPanel?.("grid");
|
| 715 |
return;
|
| 716 |
}
|
| 717 |
setLoadingKey(key);
|
|
|
|
| 720 |
await commands.showSimilar({
|
| 721 |
sampleId: result.sampleId,
|
| 722 |
layoutKey: model.layoutKey,
|
|
|
|
| 723 |
k: 10,
|
| 724 |
source: `fashion-ranked-result:${model.key}`,
|
| 725 |
focus: false,
|
|
|
|
| 765 |
React.createElement(
|
| 766 |
TextBlock,
|
| 767 |
null,
|
| 768 |
+
"Business readout for the selected shopper query.",
|
| 769 |
),
|
| 770 |
examples.length
|
| 771 |
? React.createElement(ExampleChooser, {
|
|
|
|
| 842 |
})
|
| 843 |
: null,
|
| 844 |
),
|
| 845 |
+
selectedExample && inspectableModels.length
|
| 846 |
+
? React.createElement(
|
| 847 |
+
Section,
|
| 848 |
+
{ title: "Inspect Exact Target" },
|
| 849 |
+
React.createElement(
|
| 850 |
+
TextBlock,
|
| 851 |
+
null,
|
| 852 |
+
`Exact-target summary for: ${selectedExample?.targetTitle || "target product"}.`,
|
| 853 |
+
),
|
| 854 |
+
React.createElement(ExactTargetActions, {
|
| 855 |
item: selectedExample,
|
| 856 |
+
models: inspectableModels,
|
| 857 |
loadingKey,
|
| 858 |
onSelectQuery: selectModelQuery,
|
| 859 |
+
}),
|
| 860 |
+
)
|
| 861 |
+
: null,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 862 |
warnings.length
|
| 863 |
? React.createElement(
|
| 864 |
"div",
|
Dockerfile
CHANGED
|
@@ -42,7 +42,7 @@ COPY --chown=user . .
|
|
| 42 |
|
| 43 |
ENV HYPERVIEW_HOST=0.0.0.0 \
|
| 44 |
HYPERVIEW_PORT=7860 \
|
| 45 |
-
HYPERVIEW_WORKSPACE_ID=fashion-retail-search-
|
| 46 |
HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
|
| 47 |
HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media \
|
| 48 |
DEEPFASHION_SAMPLES_PER_CATEGORY=10 \
|
|
|
|
| 42 |
|
| 43 |
ENV HYPERVIEW_HOST=0.0.0.0 \
|
| 44 |
HYPERVIEW_PORT=7860 \
|
| 45 |
+
HYPERVIEW_WORKSPACE_ID=fashion-retail-search-samples \
|
| 46 |
HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
|
| 47 |
HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media \
|
| 48 |
DEEPFASHION_SAMPLES_PER_CATEGORY=10 \
|
demo.py
CHANGED
|
@@ -18,7 +18,7 @@ import hyperview as hv
|
|
| 18 |
SPACE_DIR = Path(__file__).resolve().parent
|
| 19 |
SPACE_HOST = os.environ.get("HYPERVIEW_HOST", "127.0.0.1")
|
| 20 |
SPACE_PORT = int(os.environ.get("HYPERVIEW_PORT", "6262"))
|
| 21 |
-
WORKSPACE_ID = os.environ.get("HYPERVIEW_WORKSPACE_ID", "fashion-retail-search-
|
| 22 |
DATASET_NAME = os.environ.get("HYPERVIEW_DATASET_NAME", "deepfashion_text_search_clip_hyper3clip")
|
| 23 |
EXTENSION_DIR = SPACE_DIR / ".hyperview" / "extensions" / "fashion-search-readout"
|
| 24 |
|
|
@@ -37,6 +37,11 @@ ALLOW_CANDIDATE_FALLBACK = os.environ.get("HYPERVIEW_ALLOW_CANDIDATE_FALLBACK",
|
|
| 37 |
"true",
|
| 38 |
"yes",
|
| 39 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
EMBEDDING_MAX_ATTEMPTS = max(1, int(os.environ.get("HYPERVIEW_EMBEDDING_MAX_ATTEMPTS", "4")))
|
| 41 |
EMBEDDING_RETRY_DELAY_SECONDS = float(os.environ.get("HYPERVIEW_EMBEDDING_RETRY_DELAY_SECONDS", "15"))
|
| 42 |
RUNTIME_WARNINGS: list[str] = []
|
|
@@ -332,25 +337,20 @@ def ensure_layouts(dataset: hv.Dataset) -> dict[str, str]:
|
|
| 332 |
def build_dataset() -> tuple[hv.Dataset, dict[str, str]]:
|
| 333 |
dataset = hv.Dataset(DATASET_NAME)
|
| 334 |
add_deepfashion_samples(dataset)
|
| 335 |
-
layouts = ensure_layouts(dataset)
|
| 336 |
return dataset, layouts
|
| 337 |
|
| 338 |
|
| 339 |
-
def space_key_from_layout(layout_key: str) -> str:
|
| 340 |
-
return layout_key.split("__euclidean_umap", 1)[0].split("__poincare_umap", 1)[0]
|
| 341 |
-
|
| 342 |
-
|
| 343 |
def model_panel_props(layouts: dict[str, str]) -> list[dict[str, Any]]:
|
| 344 |
props = []
|
| 345 |
for spec in MODEL_SPECS:
|
| 346 |
-
layout_key = layouts
|
| 347 |
props.append(
|
| 348 |
{
|
| 349 |
"key": spec["key"],
|
| 350 |
"displayName": spec["display_name"],
|
| 351 |
"buttonLabel": spec["button_label"],
|
| 352 |
"layoutKey": layout_key,
|
| 353 |
-
"spaceKey": spec.get("space_key") or space_key_from_layout(layout_key),
|
| 354 |
}
|
| 355 |
)
|
| 356 |
return props
|
|
@@ -438,12 +438,12 @@ def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
|
|
| 438 |
title="Ranked Search Results",
|
| 439 |
extension="fashion-search-readout",
|
| 440 |
panel="fashion-comparison",
|
| 441 |
-
position="
|
| 442 |
props={
|
| 443 |
**shared_props,
|
| 444 |
"mode": "results",
|
| 445 |
"dockview": {
|
| 446 |
-
"closeSamplesPanel":
|
| 447 |
"hideExplorerPanel": True,
|
| 448 |
"initialWidth": int(os.environ.get("FASHION_RESULTS_WIDTH", "780")),
|
| 449 |
"minimumWidth": 620,
|
|
@@ -452,6 +452,9 @@ def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
|
|
| 452 |
},
|
| 453 |
)
|
| 454 |
|
|
|
|
|
|
|
|
|
|
| 455 |
clip_spec = MODEL_SPECS[0]
|
| 456 |
candidate_spec = MODEL_SPECS[1]
|
| 457 |
context_dockview = {
|
|
@@ -459,24 +462,12 @@ def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
|
|
| 459 |
"minimumWidth": 260,
|
| 460 |
"maximumWidth": int(os.environ.get("FASHION_CONTEXT_MAX_WIDTH", "440")),
|
| 461 |
}
|
| 462 |
-
summary_panel = hv.ui.ExtensionPanel(
|
| 463 |
-
id="fashion-buyer-readout",
|
| 464 |
-
title="Buyer Readout",
|
| 465 |
-
extension="fashion-search-readout",
|
| 466 |
-
panel="fashion-comparison",
|
| 467 |
-
position="right",
|
| 468 |
-
props={
|
| 469 |
-
**shared_props,
|
| 470 |
-
"mode": "summary",
|
| 471 |
-
"dockview": context_dockview,
|
| 472 |
-
},
|
| 473 |
-
)
|
| 474 |
clip_map = hv.ui.Scatter(
|
| 475 |
id="fashion-map-clip",
|
| 476 |
title="Context Map: CLIP",
|
| 477 |
layout_key=layouts["clip"],
|
| 478 |
position="right",
|
| 479 |
-
reference_panel_id="fashion-
|
| 480 |
direction="within",
|
| 481 |
geometry=clip_spec["geometry"],
|
| 482 |
layout_dimension=clip_spec["layout_dimension"],
|
|
@@ -493,7 +484,7 @@ def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
|
|
| 493 |
layout_dimension=candidate_spec["layout_dimension"],
|
| 494 |
props={"dockview": context_dockview},
|
| 495 |
)
|
| 496 |
-
return hv.ui.View(results_panel,
|
| 497 |
|
| 498 |
|
| 499 |
def launch_demo(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.Session:
|
|
@@ -512,15 +503,21 @@ def launch_demo(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.Session:
|
|
| 512 |
session.ui.set_active_layout(None, workspace_id=WORKSPACE_ID)
|
| 513 |
session.ui.set_selection([], workspace_id=WORKSPACE_ID)
|
| 514 |
print(f"\nHyperView DeepFashion text-search demo is running at {session.url}", flush=True)
|
| 515 |
-
|
|
|
|
|
|
|
|
|
|
| 516 |
return session
|
| 517 |
|
| 518 |
|
| 519 |
def main() -> None:
|
| 520 |
dataset, layouts = build_dataset()
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
|
|
|
|
|
|
|
|
|
| 524 |
session = launch_demo(dataset, layouts)
|
| 525 |
session.wait()
|
| 526 |
|
|
|
|
| 18 |
SPACE_DIR = Path(__file__).resolve().parent
|
| 19 |
SPACE_HOST = os.environ.get("HYPERVIEW_HOST", "127.0.0.1")
|
| 20 |
SPACE_PORT = int(os.environ.get("HYPERVIEW_PORT", "6262"))
|
| 21 |
+
WORKSPACE_ID = os.environ.get("HYPERVIEW_WORKSPACE_ID", "fashion-retail-search-samples")
|
| 22 |
DATASET_NAME = os.environ.get("HYPERVIEW_DATASET_NAME", "deepfashion_text_search_clip_hyper3clip")
|
| 23 |
EXTENSION_DIR = SPACE_DIR / ".hyperview" / "extensions" / "fashion-search-readout"
|
| 24 |
|
|
|
|
| 37 |
"true",
|
| 38 |
"yes",
|
| 39 |
}
|
| 40 |
+
ENABLE_CONTEXT_MAPS = os.environ.get("FASHION_ENABLE_CONTEXT_MAPS", "").lower() in {
|
| 41 |
+
"1",
|
| 42 |
+
"true",
|
| 43 |
+
"yes",
|
| 44 |
+
}
|
| 45 |
EMBEDDING_MAX_ATTEMPTS = max(1, int(os.environ.get("HYPERVIEW_EMBEDDING_MAX_ATTEMPTS", "4")))
|
| 46 |
EMBEDDING_RETRY_DELAY_SECONDS = float(os.environ.get("HYPERVIEW_EMBEDDING_RETRY_DELAY_SECONDS", "15"))
|
| 47 |
RUNTIME_WARNINGS: list[str] = []
|
|
|
|
| 337 |
def build_dataset() -> tuple[hv.Dataset, dict[str, str]]:
|
| 338 |
dataset = hv.Dataset(DATASET_NAME)
|
| 339 |
add_deepfashion_samples(dataset)
|
| 340 |
+
layouts = ensure_layouts(dataset) if ENABLE_CONTEXT_MAPS else {}
|
| 341 |
return dataset, layouts
|
| 342 |
|
| 343 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
def model_panel_props(layouts: dict[str, str]) -> list[dict[str, Any]]:
|
| 345 |
props = []
|
| 346 |
for spec in MODEL_SPECS:
|
| 347 |
+
layout_key = layouts.get(spec["key"])
|
| 348 |
props.append(
|
| 349 |
{
|
| 350 |
"key": spec["key"],
|
| 351 |
"displayName": spec["display_name"],
|
| 352 |
"buttonLabel": spec["button_label"],
|
| 353 |
"layoutKey": layout_key,
|
|
|
|
| 354 |
}
|
| 355 |
)
|
| 356 |
return props
|
|
|
|
| 438 |
title="Ranked Search Results",
|
| 439 |
extension="fashion-search-readout",
|
| 440 |
panel="fashion-comparison",
|
| 441 |
+
position="right",
|
| 442 |
props={
|
| 443 |
**shared_props,
|
| 444 |
"mode": "results",
|
| 445 |
"dockview": {
|
| 446 |
+
"closeSamplesPanel": False,
|
| 447 |
"hideExplorerPanel": True,
|
| 448 |
"initialWidth": int(os.environ.get("FASHION_RESULTS_WIDTH", "780")),
|
| 449 |
"minimumWidth": 620,
|
|
|
|
| 452 |
},
|
| 453 |
)
|
| 454 |
|
| 455 |
+
if not ENABLE_CONTEXT_MAPS:
|
| 456 |
+
return hv.ui.View(results_panel)
|
| 457 |
+
|
| 458 |
clip_spec = MODEL_SPECS[0]
|
| 459 |
candidate_spec = MODEL_SPECS[1]
|
| 460 |
context_dockview = {
|
|
|
|
| 462 |
"minimumWidth": 260,
|
| 463 |
"maximumWidth": int(os.environ.get("FASHION_CONTEXT_MAX_WIDTH", "440")),
|
| 464 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
clip_map = hv.ui.Scatter(
|
| 466 |
id="fashion-map-clip",
|
| 467 |
title="Context Map: CLIP",
|
| 468 |
layout_key=layouts["clip"],
|
| 469 |
position="right",
|
| 470 |
+
reference_panel_id="fashion-ranked-results",
|
| 471 |
direction="within",
|
| 472 |
geometry=clip_spec["geometry"],
|
| 473 |
layout_dimension=clip_spec["layout_dimension"],
|
|
|
|
| 484 |
layout_dimension=candidate_spec["layout_dimension"],
|
| 485 |
props={"dockview": context_dockview},
|
| 486 |
)
|
| 487 |
+
return hv.ui.View(results_panel, clip_map, candidate_map)
|
| 488 |
|
| 489 |
|
| 490 |
def launch_demo(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.Session:
|
|
|
|
| 503 |
session.ui.set_active_layout(None, workspace_id=WORKSPACE_ID)
|
| 504 |
session.ui.set_selection([], workspace_id=WORKSPACE_ID)
|
| 505 |
print(f"\nHyperView DeepFashion text-search demo is running at {session.url}", flush=True)
|
| 506 |
+
if ENABLE_CONTEXT_MAPS:
|
| 507 |
+
print(" Samples stay visible; scatter maps are opt-in context tabs.", flush=True)
|
| 508 |
+
else:
|
| 509 |
+
print(" Samples stay visible; ranked text-search results are the main demo.", flush=True)
|
| 510 |
return session
|
| 511 |
|
| 512 |
|
| 513 |
def main() -> None:
|
| 514 |
dataset, layouts = build_dataset()
|
| 515 |
+
if layouts:
|
| 516 |
+
print("Layouts:", flush=True)
|
| 517 |
+
for spec in MODEL_SPECS:
|
| 518 |
+
print(f" {spec['display_name']}: {layouts[spec['key']]}", flush=True)
|
| 519 |
+
else:
|
| 520 |
+
print("Context maps disabled; skipping embedding/layout startup.", flush=True)
|
| 521 |
session = launch_demo(dataset, layouts)
|
| 522 |
session.wait()
|
| 523 |
|