hyperview 0.6.0__tar.gz → 0.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {hyperview-0.6.0 → hyperview-0.6.2}/.agents/skills/hyperview-cli/SKILL.md +22 -12
  2. {hyperview-0.6.0 → hyperview-0.6.2}/.agents/skills/hyperview-cli/references/commands.md +74 -6
  3. {hyperview-0.6.0 → hyperview-0.6.2}/.agents/skills/hyperview-cli/references/extensions.md +28 -26
  4. {hyperview-0.6.0 → hyperview-0.6.2}/.agents/skills/hyperview-cli/references/panel-modules.md +23 -23
  5. {hyperview-0.6.0 → hyperview-0.6.2}/PKG-INFO +5 -4
  6. {hyperview-0.6.0 → hyperview-0.6.2}/README.md +1 -1
  7. {hyperview-0.6.0 → hyperview-0.6.2}/pyproject.toml +3 -2
  8. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/__init__.py +4 -0
  9. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/_version.py +2 -2
  10. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/api.py +150 -9
  11. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/cli.py +241 -14
  12. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/core/dataset.py +98 -52
  13. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/core/sample.py +8 -4
  14. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/engine.py +31 -20
  15. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/pipelines.py +22 -19
  16. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/runtime.py +501 -27
  17. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/app.py +266 -106
  18. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/404/index.html +1 -1
  19. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/404.html +1 -1
  20. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/__next.__PAGE__.txt +2 -2
  21. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/__next._full.txt +3 -3
  22. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/__next._head.txt +1 -1
  23. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/__next._index.txt +2 -2
  24. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/__next._tree.txt +2 -2
  25. hyperview-0.6.2/src/hyperview/server/static/_next/static/chunks/1daeab61a412190e.js +8 -0
  26. hyperview-0.6.2/src/hyperview/server/static/_next/static/chunks/57c4c11f21d10377.css +3 -0
  27. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._full.txt +2 -2
  28. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._head.txt +1 -1
  29. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._index.txt +2 -2
  30. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
  31. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._not-found.txt +1 -1
  32. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/__next._tree.txt +2 -2
  33. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/index.html +1 -1
  34. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_not-found/index.txt +2 -2
  35. hyperview-0.6.2/src/hyperview/server/static/index.html +1 -0
  36. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/index.txt +3 -3
  37. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/geometry.py +8 -14
  38. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/lancedb_backend.py +213 -85
  39. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/memory_backend.py +1 -1
  40. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/metrics.py +0 -27
  41. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/schema.py +2 -16
  42. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/ui.py +179 -20
  43. hyperview-0.6.0/src/hyperview/server/static/_next/static/chunks/0c17ee078faaeb62.js +0 -8
  44. hyperview-0.6.0/src/hyperview/server/static/_next/static/chunks/7acade957a14420e.css +0 -3
  45. hyperview-0.6.0/src/hyperview/server/static/index.html +0 -1
  46. {hyperview-0.6.0 → hyperview-0.6.2}/.gitignore +0 -0
  47. {hyperview-0.6.0 → hyperview-0.6.2}/LICENSE +0 -0
  48. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/core/__init__.py +0 -0
  49. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/core/selection.py +0 -0
  50. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/__init__.py +0 -0
  51. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/compute.py +0 -0
  52. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/projection.py +0 -0
  53. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/providers/__init__.py +0 -0
  54. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/embeddings/providers/lancedb_providers.py +0 -0
  55. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/extensions.py +0 -0
  56. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/figures/__init__.py +0 -0
  57. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/figures/colors.py +0 -0
  58. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/figures/render.py +0 -0
  59. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/__init__.py +0 -0
  60. {hyperview-0.6.0/src/hyperview/server/static/_next/static/VXRlYGcnYv3zp0mzwnWWb → hyperview-0.6.2/src/hyperview/server/static/_next/static/_W0V_8-00bWcS7EniWKJf}/_buildManifest.js +0 -0
  61. {hyperview-0.6.0/src/hyperview/server/static/_next/static/VXRlYGcnYv3zp0mzwnWWb → hyperview-0.6.2/src/hyperview/server/static/_next/static/_W0V_8-00bWcS7EniWKJf}/_clientMiddlewareManifest.json +0 -0
  62. {hyperview-0.6.0/src/hyperview/server/static/_next/static/VXRlYGcnYv3zp0mzwnWWb → hyperview-0.6.2/src/hyperview/server/static/_next/static/_W0V_8-00bWcS7EniWKJf}/_ssgManifest.js +0 -0
  63. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/567993cf36cd4ab1.js +0 -0
  64. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/661a08547c83f565.js +0 -0
  65. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/86c1fc4cf542f408.js +0 -0
  66. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  67. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/a6dad97d9634a72d.js.map +0 -0
  68. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/e954ba82c0a04100.js +0 -0
  69. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/eac713f252f03efd.js +0 -0
  70. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/f29dd35a99c216ea.js +0 -0
  71. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/chunks/turbopack-cb59e03a04a579d1.js +0 -0
  72. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/1bffadaabf893a1e-s.7cd81963.woff2 +0 -0
  73. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/2bbe8d2671613f1f-s.76dcb0b2.woff2 +0 -0
  74. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/2c55a0e60120577a-s.2a48534a.woff2 +0 -0
  75. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/5476f68d60460930-s.c995e352.woff2 +0 -0
  76. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2 +0 -0
  77. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/9c72aa0f40e4eef8-s.18a48cbc.woff2 +0 -0
  78. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/server/static/_next/static/media/ad66f9afd8947f86-s.7a40eb73.woff2 +0 -0
  79. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/skill_install.py +0 -0
  80. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/__init__.py +0 -0
  81. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/backend.py +0 -0
  82. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/storage/config.py +0 -0
  83. {hyperview-0.6.0 → hyperview-0.6.2}/src/hyperview/tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hyperview-cli
3
- description: Use HyperView's control-plane CLI for hyperview serve, dataset create, workspace create, embeddings compute, layouts compute, browserless paper figure export, runtime jobs, ui layout set, ui selection set, ui panel add, extension add, tools run, panel modules, backend tools, and local HyperView extension workflows.
3
+ description: Use HyperView's control-plane CLI for hyperview serve, dataset create, workspace create, embeddings compute, layouts compute, browserless paper figure export, runtime jobs, ui layout set, ui selection set, ui panel add/update, extension add, tools run, panel modules, Python tools, and local HyperView extension workflows.
4
4
  license: MIT
5
5
  compatibility: Requires Python 3.10-3.13 and the hyperview CLI (`uv tool install --python 3.12 hyperview`). Runtime-control commands require a running HyperView server.
6
6
  metadata:
@@ -29,10 +29,10 @@ HyperView currently supports Python 3.10 through 3.13; `--python 3.12` keeps the
29
29
  - Start or control a running HyperView runtime.
30
30
  - Register a custom embedding provider.
31
31
  - Compute embeddings or layouts without restarting the UI.
32
- - Export paper-ready static 3D embedding figures without a browser or Node runtime.
32
+ - Export paper-ready static 3D embedding figures without opening the UI.
33
33
  - Switch the active workspace, layout, or selection in a running session.
34
34
  - Add, remove, or compose extension-backed panel instances.
35
- - Create, install, reload, or test a local extension with Python backend tools and a frontend panel.
35
+ - Create, install, reload, or use a local extension with Python tools and browser panels.
36
36
 
37
37
  ## Core workflow
38
38
 
@@ -50,32 +50,42 @@ HyperView currently supports Python 3.10 through 3.13; `--python 3.12` keeps the
50
50
  - One dataset per workspace.
51
51
  - Datasets are created separately from workspaces.
52
52
  - The workspace owns the dataset selection.
53
- - `ui layout set` changes the active layout and the frontend opens the matching built-in scatter panel.
53
+ - `ui layout set` changes the active layout and opens the matching built-in scatter panel.
54
54
  - `ui similarity set` selects an anchor sample and pins the nearest-neighbor context to an explicit layout or space.
55
- - Runtime-added panels can be typed scatter instances bound to explicit layout keys, or extension-backed panel modules loaded into the host React tree.
55
+ - Runtime-added panels can be built-in samples panels, typed scatter instances bound to explicit layout keys, or extension-backed panel modules loaded into the host React tree.
56
56
  - Runtime-added panels use the stable `HyperViewPanelSDK` surface on `window`.
57
57
  - Extensions are repo-local folders with `extension.toml`, optional Python tools, and optional panel modules.
58
- - Extension panels call backend tools through `HyperViewPanelSDK.hooks.useTool()` or `hyperview tools run`.
58
+ - Extension panels call Python tools through `HyperViewPanelSDK.hooks.useTool()` or `hyperview tools run`.
59
59
  - Extensions define reusable tools/panels; workspace views compose concrete panel instances and layout. In Python launch scripts, register extensions with `session.ui.add_extension(...)` and place panels with `hv.ui.ExtensionPanel(...)`.
60
- - In practice, create datasets and workspaces before starting the runtime for that workspace. The current runtime loads workspace registry state on startup.
60
+ - In practice, create datasets and workspaces before starting the runtime for that workspace.
61
61
  - `figure export` is browserless and supports 3D layouts only. It reuses the persisted 3D camera for the layout when available, otherwise it chooses a paper-oriented default view.
62
62
  - Paper figure defaults are square, white-background, opaque PNGs with a faint sphere guide and direct labels for small label sets.
63
63
 
64
64
  Read [references/commands.md](references/commands.md) for command recipes covering datasets, workspaces, providers, embeddings, layouts, paper figures, runtime UI state, selections, and jobs.
65
65
  Read [references/panel-modules.md](references/panel-modules.md) when the task involves authoring a browser panel module.
66
- Read [references/extensions.md](references/extensions.md) when the task involves packaging or registering custom panel code or backend tools.
66
+ Read [references/extensions.md](references/extensions.md) when the task involves packaging or registering custom panel code or Python tools.
67
67
 
68
68
  ## Agent guidance
69
69
 
70
- - Prefer CLI commands over direct file edits when the goal is to operate a running HyperView session.
70
+ - Prefer CLI commands when the goal is to operate a running HyperView session.
71
71
  - Treat dataset creation and workspace binding as separate steps when needed: `dataset create ...` creates persisted data, `workspace create --dataset ...` or `workspace set-dataset ...` binds it to a workspace.
72
72
  - Prefer `workspace create --dataset ...` over separate create and dataset-attach calls when setting up a new workspace.
73
+ - In Python dataset setup code, use public ingestion helpers such as `dataset.add_samples([...])` or `dataset.add_images_dir(...)`.
74
+ - Prefer built-in providers before registering custom providers. For Hyper3-CLIP, use `dataset.compute_embeddings(model="hyper3-clip-v0.5", provider="hyper-models")`.
75
+ - When a project truly needs a custom Python provider, use `hyperview provider register ...` from the CLI or `hv.register_provider(...)` in Python.
73
76
  - For custom panel code, create an extension under `.hyperview/extensions/<extension-name>/`; do not register arbitrary panel module files directly.
74
77
  - For side-by-side embedding comparisons, add typed scatter panels through `hyperview ui panel add --kind scatter --layout-key ... --reference-panel-id ... --direction right`.
78
+ - Use first-class view layout fields for panel sizing and visibility: `hv.ui.PanelLayout(width=..., min_width=...)` in Python, or `hyperview ui panel resize/move/focus/close/show` from the CLI. Do not pass Dockview-specific sizing through panel props.
79
+ - To retitle an existing runtime panel or replace its props, use `hyperview ui panel update --panel-id ... --title ... --props-json ...` instead of remove/re-add when preserving panel identity matters.
75
80
  - For nearest-neighbor comparisons, use `hyperview ui similarity set --sample-id ... --layout-key ...` or panel SDK `commands.showSimilar(...)`; do not infer neighbor space from whichever scatter panel is focused.
76
81
  - For extensions, prefer `.hyperview/extensions/<extension-name>/` in the project root. `hyperview serve` auto-discovers those folders and attaches them to the launched workspace, so they can live in version control with the dataset/project code.
77
- - For demos/spaces that launch HyperView from Python, compose panels with `hv.ui.Horizontal`, `hv.ui.Vertical`, `hv.ui.Scatter`, and `hv.ui.ExtensionPanel`; keep extension manifests focused on reusable panel/tool definitions.
82
+ - For demos/spaces that launch HyperView from Python, compose panels with `hv.ui.Horizontal`, `hv.ui.Vertical`, `hv.ui.Tabs`, `hv.ui.Grid`, `hv.ui.Scatter`, `hv.ui.Samples`, `hv.ui.ExtensionPanel`, and `hv.ui.PanelLayout`; keep extension manifests focused on reusable panel/tool definitions.
83
+ - Keep layout orchestration out of panel modules. A panel should not close, hide, or rearrange sibling panels on mount; use `hv.ui.View(...)` or `hyperview ui panel ...` to compose the workspace.
84
+ - Treat local `focusPanel` and `closePanel` as transient user-action helpers, not as startup layout machinery. For durable control from a panel, use SDK commands such as `setActivePanel`, `setPanelVisible`, `resizePanel`, and `movePanel`.
85
+ - Pass only documented panel props through `hv.ui.ExtensionPanel(..., props=...)`.
78
86
  - Tools can write files under `ctx.extension_storage` and return `ctx.url_for(path)` for panel-renderable artifact URLs.
87
+ - Put query results, benchmark tables, contact sheets, and other generated artifacts behind extension tools or compact panel props. Do not embed large base64 payloads or generated datasets inside panel JavaScript.
88
+ - Keep cross-panel coordination in host/runtime state. Do not use `window.dispatchEvent` / `window.addEventListener` as shared panel state.
79
89
  - Keep extensions self-contained: `extension.toml`, `tools.py`, `panel.js` or `panel.jsx`, and any local assets in the same folder.
80
90
  - Prefer `--json` output when chaining commands or inspecting results programmatically.
81
91
  - Wait for embedding/layout jobs to finish before issuing layout-switch commands that depend on their results.
@@ -83,7 +93,7 @@ Read [references/extensions.md](references/extensions.md) when the task involves
83
93
  - For provider args, use repeated `--provider-arg key=value` flags.
84
94
  - Treat the workspace as the durable unit. Changing datasets means setting a new workspace dataset, not switching among many datasets inside one workspace.
85
95
  - Prefer panel modules over raw HTML. The panel system no longer relies on iframes.
86
- - For paper diagrams, prefer `hyperview figure export` over browser screenshots unless the user explicitly needs exact UI chrome. It does not require Playwright, browser bundling, or Node at runtime.
96
+ - For paper diagrams, prefer `hyperview figure export` over browser screenshots unless the user explicitly needs exact UI chrome.
87
97
  - For publication figures, keep the defaults first: `--theme light`, `--guide-style paper`, and `--legend auto`. Use `--show-selection` only when selected samples are meaningful and will be explained in the caption.
88
98
  - The first `uv run hyperview ...` invocation in a session can take 30+ seconds (torch/datasets imports). Allow generous timeouts and avoid sending SIGINT.
89
99
 
@@ -95,4 +105,4 @@ The runtime exposes JSON discovery endpoints alongside the CLI. Use them to obta
95
105
  - `GET /api/embeddings?workspace_id=<ws>` &mdash; the active or default layout, including `layout_key`, `geometry`, and sample `ids`. Use the returned `layout_key` for `hyperview ui layout set --layout-key ...` and pick from `ids` for `hyperview ui selection set --ids ...`.
96
106
  - `GET /api/tools` &mdash; registered tool URIs (also returned by `hyperview tools list --json`).
97
107
 
98
- Layout keys encode geometry and dimension as a substring (e.g. `..._euclidean_umap__2d_...`, `..._hyperbolic_umap__3d_...`). Match on those substrings when filtering by geometry/dimension.
108
+ Prefer layout metadata over parsing layout-key strings. Use `/api/dataset`, `usePanelLayouts()`, or `dataset.list_layouts()` when filtering by geometry, dimension, model, or space.
@@ -95,13 +95,29 @@ hyperview status --json
95
95
 
96
96
  ## Providers, Embeddings, and Layouts
97
97
 
98
- Register a custom provider:
98
+ Use built-in providers directly when possible. Hyper3-CLIP is available through
99
+ the `hyper-models` provider:
100
+
101
+ ```python
102
+ dataset.compute_embeddings(model="hyper3-clip-v0.5", provider="hyper-models")
103
+ ```
104
+
105
+ Register a custom provider only when the model is not available through a
106
+ built-in provider:
99
107
 
100
108
  ```bash
101
109
  hyperview provider register my-provider \
102
110
  --import-path my_pkg.provider:MyProvider
103
111
  ```
104
112
 
113
+ The same registration is available from Python:
114
+
115
+ ```python
116
+ import hyperview as hv
117
+
118
+ hv.register_provider("my-provider", "my_pkg.provider:MyProvider", overwrite=True)
119
+ ```
120
+
105
121
  Compute checkpoint-backed embeddings and a layout:
106
122
 
107
123
  ```bash
@@ -144,7 +160,7 @@ hyperview figure export figures/embedding-sphere.png \
144
160
 
145
161
  If `--layout` is omitted, HyperView uses the active 3D layout when one is set, otherwise the first available 3D layout. Use `--layout active` when you specifically want the live UI's active layout and want the command to fail if none is active.
146
162
 
147
- The export path is pure Python and does not require Playwright, browser bundling, Node, or a running frontend. It supports 3D layouts only; 2D layouts are rejected with a validation message.
163
+ The export path does not require opening the UI. It supports 3D layouts only; 2D layouts are rejected with a validation message.
148
164
 
149
165
  Paper defaults are tuned for academic figures:
150
166
 
@@ -220,6 +236,20 @@ hyperview ui panel add \
220
236
  --extension label-histogram \
221
237
  --extension-panel label-histogram \
222
238
  --position right \
239
+ --width 340 \
240
+ --min-width 280 \
241
+ ```
242
+
243
+ Add the built-in samples panel through the same runtime panel API:
244
+
245
+ ```bash
246
+ hyperview ui panel add \
247
+ --workspace research \
248
+ --panel-id samples \
249
+ --kind builtin \
250
+ --builtin-panel samples \
251
+ --props-json '{"mode":"browse"}' \
252
+ --position right
223
253
  ```
224
254
 
225
255
  Add two runtime scatter panels bound to explicit layouts, side by side:
@@ -244,8 +274,7 @@ hyperview ui panel add \
244
274
  --direction right
245
275
  ```
246
276
 
247
- Python launch scripts can encode the same composition without calling runtime
248
- internals:
277
+ Python launch scripts can encode the same composition:
249
278
 
250
279
  ```python
251
280
  view = hv.ui.View(
@@ -253,13 +282,52 @@ view = hv.ui.View(
253
282
  hv.ui.Scatter("uncha-poincare", title="UNCHA", layout_key=uncha_layout),
254
283
  hv.ui.Scatter("hycoclip-poincare", title="HyCoCLIP", layout_key=hycoclip_layout),
255
284
  ),
256
- hv.ui.ExtensionPanel("notes", extension="notes", panel="notes", position="right"),
285
+ hv.ui.ExtensionPanel(
286
+ "notes",
287
+ extension="notes",
288
+ panel="notes",
289
+ position="right",
290
+ layout=hv.ui.PanelLayout(width=340, min_width=280),
291
+ ),
292
+ active_panel="notes",
257
293
  )
258
294
  session = hv.launch(dataset, block=False)
259
295
  session.ui.add_extension(".hyperview/extensions/notes")
260
296
  session.ui.apply_view(view)
261
297
  ```
262
298
 
299
+ Update an existing runtime panel title or props without changing its identity:
300
+
301
+ ```bash
302
+ hyperview ui panel update \
303
+ --workspace research \
304
+ --panel-id samples \
305
+ --title "Ranked Samples" \
306
+ --props-json '{"mode":"ranked","rank":{"anchorSampleId":"<sample-id>","layoutKey":"<layout-key>","k":18}}' \
307
+ --json
308
+ ```
309
+
310
+ Resize, move, focus, hide, or show a runtime panel through durable view state:
311
+
312
+ ```bash
313
+ hyperview ui panel resize \
314
+ --workspace research \
315
+ --panel-id notes \
316
+ --width 380 \
317
+ --min-width 300
318
+
319
+ hyperview ui panel move \
320
+ --workspace research \
321
+ --panel-id notes \
322
+ --position right \
323
+ --reference-panel-id samples \
324
+ --direction right
325
+
326
+ hyperview ui panel focus --workspace research --panel-id notes
327
+ hyperview ui panel close --workspace research --panel-id notes
328
+ hyperview ui panel show --workspace research --panel-id notes
329
+ ```
330
+
263
331
  Remove a runtime panel by id:
264
332
 
265
333
  ```bash
@@ -286,7 +354,7 @@ hyperview ui similarity clear --workspace research
286
354
 
287
355
  ## Extensions and Tools
288
356
 
289
- Create backend-plus-frontend extensions under `.hyperview/extensions/<name>/` so they can be versioned with the project and auto-registered on `hyperview serve`. For a server that is already running, install one explicitly:
357
+ Create extensions under `.hyperview/extensions/<name>/` so they can be versioned with the project and auto-registered on `hyperview serve`. For a server that is already running, install one explicitly:
290
358
 
291
359
  ```bash
292
360
  hyperview extension add .hyperview/extensions/selection-profile \
@@ -1,6 +1,6 @@
1
1
  # Extensions
2
2
 
3
- Use this guide when creating a HyperView extension that includes backend Python tools and a frontend panel.
3
+ Use this guide when creating a HyperView extension that includes Python tools and a browser panel.
4
4
 
5
5
  ## Model
6
6
 
@@ -11,6 +11,11 @@ layout or know about sibling panels. Compose concrete demo/workspace layouts
11
11
  from Python with `hv.ui.View(...)` and `session.ui.apply_view(...)`, or from
12
12
  the CLI with `hyperview ui panel add --extension ...`.
13
13
 
14
+ Extensions should also keep generated data out of panel source. If a panel
15
+ needs ranked query results, benchmark summaries, contact sheets, or other
16
+ artifacts, generate or read them from an extension tool and return compact JSON or
17
+ URLs from `ctx.url_for(...)`.
18
+
14
19
  Preferred shape for agent-authored, project-versioned extensions:
15
20
 
16
21
  ```text
@@ -46,7 +51,7 @@ Treat `position` as a weak default for where the panel usually belongs. Cross-pa
46
51
  relationships such as "this scatter is right of that scatter" belong to the
47
52
  workspace view/composition layer, not the extension manifest.
48
53
 
49
- ## Backend Tools
54
+ ## Python Tools
50
55
 
51
56
  Tools are plain Python functions decorated with `@tool("namespace.name")`. The first argument is a `RunContext`.
52
57
 
@@ -94,9 +99,9 @@ Use `ctx.dataset` for active dataset reads, `ctx.workspace` for workspace UI sta
94
99
  - `sample.label: str | None`
95
100
  - `sample.metadata: dict[str, Any]`
96
101
 
97
- ## Frontend Panel
102
+ ## Browser Panel
98
103
 
99
- Panel modules must be browser-loadable JavaScript modules. They export a default React component or named `Panel`, and use `globalThis.HyperViewPanelSDK` rather than importing from app internals.
104
+ Panel modules must be browser-loadable JavaScript modules. They export a default React component or named `Panel`, and use `globalThis.HyperViewPanelSDK`.
100
105
 
101
106
  ```js
102
107
  const sdk = globalThis.HyperViewPanelSDK;
@@ -136,16 +141,23 @@ Available SDK hooks include `usePanelRuntimeState`, `usePanelHostState`, `usePan
136
141
 
137
142
  For dataset-wide panel behavior, prefer `usePanelClient().querySamples(...)`,
138
143
  `aggregateSamples(...)`, `selectSamples(...)`, `getSamplesByIds(...)`,
139
- `searchSimilar(...)`, or a backend tool over scanning a fixed
144
+ `searchSimilar(...)`, or an extension tool over scanning a fixed
140
145
  `listSamples({ limit: ... })` page or hand-building API URLs in the browser.
146
+ Sample reads default to `includeThumbnails: false`; use each sample's
147
+ `thumbnail_url` for images, and request inline thumbnails only when a panel
148
+ explicitly needs base64 data.
141
149
 
142
- Use `usePanelHostState()` for low-level synchronized host state instead of
143
- importing frontend internals. Use narrower hooks such as `usePanelSelection()`,
150
+ Use `usePanelHostState()` for synchronized host state. Use narrower hooks such as `usePanelSelection()`,
144
151
  `usePanelSelectedSamples()`, `usePanelHover()`, `usePanelLayouts()`, and
145
152
  `usePanelLayoutView()` when the panel only needs one part of that state. Use
146
153
  `usePanelCommands()` for host writes. Selection and active-layout changes
147
- persist to runtime UI state by default; pass `{ persist: false }` only for
148
- local transient UI changes.
154
+ update host state immediately and persist to runtime UI state in the
155
+ background by default. Pass `{ persist: true }` only when the caller must wait
156
+ for durable runtime state, and pass `{ persist: false }` for local transient UI
157
+ changes.
158
+
159
+ Do not use browser globals such as `window.dispatchEvent` to synchronize panels,
160
+ and use SDK commands for control-plane writes.
149
161
 
150
162
  `useTool(uri)` returns `{ run, result, loading, error, reset }`. Call `run(params)` to invoke the tool; `result` holds the last successful return value, `loading` is true while a call is in flight, and `error` is the last failure message (or `null`). See [panel-modules.md](panel-modules.md#hook-return-shapes) for the full hook return shape table.
151
163
 
@@ -195,13 +207,13 @@ hyperview tools run selection_profile.summarize \
195
207
  --json
196
208
  ```
197
209
 
198
- Reload after editing files:
210
+ Reload an installed extension:
199
211
 
200
212
  ```bash
201
213
  hyperview extension reload selection-profile --json
202
214
  ```
203
215
 
204
- Compose a demo view from Python instead of importing runtime internals:
216
+ Compose a demo view from Python:
205
217
 
206
218
  ```python
207
219
  import hyperview as hv
@@ -216,7 +228,9 @@ view = hv.ui.View(
216
228
  extension="catalog-readout",
217
229
  panel="readout",
218
230
  position="right",
231
+ layout=hv.ui.PanelLayout(width=340, min_width=280),
219
232
  ),
233
+ active_panel="readout",
220
234
  )
221
235
 
222
236
  session = hv.launch(dataset, block=False)
@@ -224,21 +238,9 @@ session.ui.add_extension(".hyperview/extensions/catalog-readout")
224
238
  session.ui.apply_view(view)
225
239
  ```
226
240
 
227
- ## Verification
228
-
229
- A good extension smoke test proves all of these paths:
230
-
231
- - `extension add` returns the extension with expected tools and panel definitions.
232
- - `GET /api/tools` (or `hyperview tools list --json`) includes the tool URI.
233
- - `hyperview tools run ...` returns data from the active dataset.
234
- - Tool-generated files under `ctx.extension_storage` are fetchable from URLs returned by `ctx.url_for(...)`.
235
- - `GET /api/runtime?workspace_id=<workspace>` includes the panel under `workspace.ui.custom_panels[*]` with `data.module_src` set to a `/api/panels/content/<workspace>/<panel-id>/<file>` URL.
236
- - Fetching `data.module_src` returns `application/javascript` with your module body.
237
- - In the browser, the panel imports successfully and a `useTool()` call returns a result.
238
-
239
241
  ## Constraints
240
242
 
241
243
  - Treat extensions as trusted local code. Python tools are imported and executed in the HyperView runtime process.
242
- - Do not use bare npm imports in panel modules unless you bundle first.
243
- - Keep extension source outside `frontend/src`; the runtime loads panel modules from local extension files.
244
- - Keep extension examples small and high-level. Avoid private HyperView APIs in user-facing examples.
244
+ - Panel modules should use the SDK global and extension-local assets.
245
+ - Keep extension files under `.hyperview/extensions/<name>/`.
246
+ - Keep extension examples small and high-level. Use documented HyperView APIs.
@@ -11,17 +11,16 @@ Runtime custom panels are now panel modules:
11
11
  - the user writes a local JavaScript module file
12
12
  - the module is declared in an extension manifest
13
13
  - the module is instantiated through `hv.ui.ExtensionPanel(...)` or `hyperview ui panel add --extension ...`
14
- - HyperView loads that module directly into the host React tree
14
+ - HyperView loads that module through the host panel system
15
15
  - the module can use the stable `window.HyperViewPanelSDK` surface
16
16
 
17
17
  Built-in panels and runtime panels now share the same host panel system.
18
18
 
19
- Use this surface for frontend-only panel code. Package it as an extension even
19
+ Use this surface for browser panel code. Package it as an extension even
20
20
  when it does not need Python tools. If the task is to open several panels in a
21
21
  particular arrangement, use a workspace view from Python
22
22
  (`hv.ui.View(...)` with `hv.launch(..., view=...)`) or the CLI `hyperview ui ...`
23
- commands. Do not import `HyperViewRuntime`, `CustomPanelSpec`, or `Session` from
24
- demo/user-facing scripts just to arrange panels.
23
+ commands.
25
24
 
26
25
  ## Panel Module Contract
27
26
 
@@ -89,16 +88,16 @@ Current global SDK fields:
89
88
  Important distinction:
90
89
 
91
90
  - `usePanelSamplesView()` gives access to host-managed collection state and is the best hook for panels that should stay synchronized with the visible HyperView UI.
92
- - `usePanelHostState()` gives low-level read access to the same host state used by built-in panels, without importing frontend internals.
93
- - `usePanelClient()` or `createClient()` is the escape hatch for direct backend reads and control-plane calls.
94
- - `useTool(uri)` calls an installed backend tool registered by an extension and returns `{ loading, result, error, run, reset }`.
91
+ - `usePanelHostState()` gives read access to the same host state used by built-in panels.
92
+ - `usePanelClient()` is an escape hatch for API data reads that are not already exposed through host state or commands.
93
+ - `useTool(uri)` calls an installed Python tool registered by an extension and returns `{ loading, result, error, run, reset }`.
95
94
 
96
95
  ### Hook return shapes
97
96
 
98
- Verified against the current `panel-sdk` surface:
97
+ Current hook return shapes:
99
98
 
100
99
  - `usePanelSelection()` → `{ selectedIds: string[], selectionSource: SelectionUpdateSource }`
101
- - `usePanelCommands()` → `{ setLabelFilter, setHoveredId, clearLassoSelection, clearSelection(): void, setSelection(ids, { source?, persist?, clearLasso? }): Promise<RuntimeSnapshot | null>, showSimilar({ sampleId, layoutKey?, spaceKey?, k?, source?, focus?, persist? }): Promise<RuntimeSnapshot | null>, setActiveLayout(layoutKey, { persist? }): Promise<RuntimeSnapshot | null>, setLayoutViewCamera(layoutKey, camera3d): void, setLayoutViewCameraPersisted(layoutKey, camera3d): Promise<null>, focusPanel(panelId): boolean, focusBuiltin(role): boolean, focusPanelByRole(role): boolean, closePanel(panelId): boolean }`
100
+ - `usePanelCommands()` → `{ setLabelFilter, setHoveredId, clearLassoSelection, clearSelection(): void, setSelection(ids, { source?, persist?, clearLasso? }): Promise<RuntimeSnapshot | null>, showSimilar({ sampleId, layoutKey, k?, source?, focus?, persist? }): Promise<RuntimeSnapshot | null>, setActiveLayout(layoutKey, { persist? }): Promise<RuntimeSnapshot | null>, setLayoutViewCamera(layoutKey, camera3d): void, setLayoutViewCameraPersisted(layoutKey, camera3d): Promise<null>, setPanelLayout(panelId, { width?, height?, minWidth?, minHeight?, maxWidth?, maxHeight? }), resizePanel(panelId, { width?, height?, minWidth?, minHeight?, maxWidth?, maxHeight? }), movePanel(panelId, { position, referencePanelId?, direction? }), setPanelVisible(panelId, visible), setActivePanel(panelId), focusPanel(panelId): boolean, focusBuiltin(role): boolean, focusPanelByRole(role): boolean, closePanel(panelId): boolean }`. `showSimilar` is layout-scoped: pass the layout key and HyperView resolves the associated embedding space automatically. `persist` accepts `true`, `false`, or `"background"` for selection/layout/similarity commands; omitted/`"background"` updates local state immediately and writes runtime state asynchronously, `true` waits for runtime persistence, and `false` is local-only.
102
101
  - `usePanelHover()` → `{ hoveredId, setHoveredId(id), clearHover() }`
103
102
  - `usePanelLayoutView(layoutKey?)` → `{ layoutKey, view, camera3d, setCamera3d(camera3d) }`
104
103
  - `usePanelLayouts()` → `{ layouts, spaces, get(layoutKey), getSpace(spaceKey), find(query), filter(query) }`; query supports `layoutKey`, `spaceKey`, `geometry`, `modelId`, and `dimension`.
@@ -109,9 +108,13 @@ Verified against the current `panel-sdk` surface:
109
108
  - `usePanelUiState()` → `{ sampleGridSize, setSampleGridSize, scatterLabelOverlayMode, setScatterLabelOverlayMode }`
110
109
  - `usePanelDatasetInfo()` / `usePanelSamples()` / `usePanelSamplesView()` → host-managed dataset and view state
111
110
  - `useTool(uri)` → `{ loading: boolean, result: TResult | null, error: string | null, run(params?): Promise<TResult | null>, reset(): void }`
112
- - `usePanelClient()` → low-level client; pair with `createClient(workspaceId)` for direct API calls. Useful methods include `querySamples`, `aggregateSamples`, `getSamplesByIds`, `searchSimilar`, `setSimilarityQuery`, `clearSimilarityQuery`, `setSelection`, and `selectSamples`.
111
+ - `usePanelClient()` → API data client. Prefer host hooks and `usePanelCommands()` for UI state; useful data methods include `querySamples`, `aggregateSamples`, `getSamplesByIds`, `searchSimilar`, and `selectSamples`.
113
112
 
114
- To clear the current selection from a panel and persist it to the runtime, use `await usePanelCommands().setSelection([])`. Pass `{ persist: false }` only for local transient UI changes.
113
+ Sample reads default to `includeThumbnails: false` and return `thumbnail_url`
114
+ for image rendering. Request inline thumbnails only when the panel specifically
115
+ needs base64 thumbnail payloads.
116
+
117
+ To clear the current selection from a panel and enqueue runtime persistence, use `await usePanelCommands().setSelection([])`. Pass `{ persist: true }` when the code must wait for runtime persistence, and pass `{ persist: false }` only for local transient UI changes.
115
118
 
116
119
  ## Placement
117
120
 
@@ -141,14 +144,6 @@ hyperview ui panel add \
141
144
  --position right
142
145
  ```
143
146
 
144
- ## Verification
145
-
146
- After `hyperview ui panel add --extension ...`:
147
-
148
- - `curl 'http://127.0.0.1:6262/api/runtime?workspace_id=<ws>'` should list the panel under `workspace.ui.custom_panels[*]` with `data.module_src` set to a `/api/panels/content/<ws>/<panel-id>/<file>` URL.
149
- - Fetching `data.module_src` should return `application/javascript` with your module body.
150
- - The panel should appear in the live UI in the requested `position` slot.
151
-
152
147
  ## Good Practices
153
148
 
154
149
  - Prefer panel modules over HTML or iframe content.
@@ -160,12 +155,17 @@ After `hyperview ui panel add --extension ...`:
160
155
  - Use `usePanelClient()` only for data that is not already available through the host state.
161
156
  - Use `usePanelClient().querySamples(...)`, `aggregateSamples(...)`, or `selectSamples(...)` for dataset-wide behavior instead of fixed-limit client scans.
162
157
  - Use `usePanelClient().searchSimilar(...)` instead of hand-building `/api/search/similar/...` URLs.
158
+ - Use `commands.showSimilar({ sampleId, layoutKey })` for nearest-neighbor UI state; pass the layout key and let HyperView resolve the embedding space.
159
+ - Use SDK commands or client methods for control-plane writes.
160
+ - Use `setActivePanel`, `setPanelVisible`, `resizePanel`, and `movePanel` when a panel needs to durably control panel view state. Use local `focusPanel` and `closePanel` only for transient user actions.
161
+ - Do not use `window.dispatchEvent` / `window.addEventListener` to synchronize panel state. Keep shared state in the host/runtime model, or keep the interaction inside one owner panel until a public shared-state hook exists.
162
+ - Do not use `focusPanel` or `closePanel` from mount effects to create the initial workspace layout. Compose startup layout with `hv.ui.View(...)` or CLI panel commands.
163
+ - Pass only documented panel props.
164
+ - Do not embed large generated result sets, base64 contact sheets, or evaluation artifacts in panel JavaScript. Use compact props, extension assets, or extension tools that return artifact URLs.
163
165
  - Keep the panel self-contained under `.hyperview/extensions/<extension-name>/`.
164
166
  - If the panel needs sibling assets, keep them next to the module and reference them with relative URLs.
165
- - Do not render a second title/header inside a normal Dockview runtime panel unless there is a strong reason. Dockview already provides the tab title. Built-in center and runtime panels should usually start with the standardized `PanelToolbar` row.
167
+ - Avoid duplicate title/header rows unless the panel has a specific reason. Built-in center and runtime panels should usually start with the standardized `PanelToolbar` row.
166
168
 
167
169
  ## Current Limitation
168
170
 
169
- Panel modules should currently be authored as browser-loadable JavaScript modules.
170
-
171
- If an agent wants TypeScript or JSX ergonomics, it should bundle or transpile to JavaScript before registration.
171
+ Panel modules must be browser-loadable JavaScript modules.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperview
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Open-source dataset curation with hyperbolic embeddings visualization
5
5
  Project-URL: Homepage, https://github.com/Hyper3Labs/HyperView
6
6
  Project-URL: Documentation, https://github.com/Hyper3Labs/HyperView#readme
@@ -28,8 +28,8 @@ Requires-Dist: embed-anything>=0.7.0
28
28
  Requires-Dist: esbuild-py>=0.1.6
29
29
  Requires-Dist: fastapi>=0.128.0
30
30
  Requires-Dist: huggingface-hub<2.0,>=1.11.0
31
- Requires-Dist: hyper-models>=0.2.0
32
- Requires-Dist: lancedb>=0.26.1
31
+ Requires-Dist: hyper-models>=0.3.0
32
+ Requires-Dist: lancedb>=0.33.0
33
33
  Requires-Dist: numpy<2.4,>=1.26.4
34
34
  Requires-Dist: pillow>=12.1.0
35
35
  Requires-Dist: pyarrow>=22.0.0
@@ -44,6 +44,7 @@ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
44
44
  Requires-Dist: pytest>=9.0.2; extra == 'dev'
45
45
  Requires-Dist: ruff>=0.14.13; extra == 'dev'
46
46
  Provides-Extra: ml
47
+ Requires-Dist: hyper-models[ml]>=0.3.0; extra == 'ml'
47
48
  Requires-Dist: timm>=1.0.0; extra == 'ml'
48
49
  Requires-Dist: torch>=2.9.1; extra == 'ml'
49
50
  Requires-Dist: torchvision>=0.24.1; extra == 'ml'
@@ -155,7 +156,7 @@ If you use HyperView in research, please cite:
155
156
  author = {{Hyper3Labs}},
156
157
  title = {HyperView: An Interactive Geometric Workbench for Embedding Space Analysis},
157
158
  year = {2026},
158
- version = {0.5.0},
159
+ version = {0.6.2},
159
160
  url = {https://github.com/Hyper3Labs/HyperView}
160
161
  }
161
162
  ```
@@ -104,7 +104,7 @@ If you use HyperView in research, please cite:
104
104
  author = {{Hyper3Labs}},
105
105
  title = {HyperView: An Interactive Geometric Workbench for Embedding Space Analysis},
106
106
  year = {2026},
107
- version = {0.5.0},
107
+ version = {0.6.2},
108
108
  url = {https://github.com/Hyper3Labs/HyperView}
109
109
  }
110
110
  ```
@@ -28,14 +28,14 @@ dependencies = [
28
28
  "uvicorn[standard]>=0.40.0",
29
29
  "embed-anything>=0.7.0",
30
30
  "huggingface-hub>=1.11.0,<2.0",
31
- "hyper-models>=0.2.0", # PyPI package: https://pypi.org/project/hyper-models/
31
+ "hyper-models>=0.3.0", # PyPI package: https://pypi.org/project/hyper-models/
32
32
  "numpy>=1.26.4,<2.4",
33
33
  "umap-learn>=0.5.11",
34
34
  "pillow>=12.1.0",
35
35
  "pydantic>=2.12.5",
36
36
  "aiofiles>=25.1.0",
37
37
  "datasets>=4.5.0",
38
- "lancedb>=0.26.1",
38
+ "lancedb>=0.33.0",
39
39
  "pyarrow>=22.0.0",
40
40
  "esbuild-py>=0.1.6",
41
41
  "tomli>=2.0; python_version<'3.11'",
@@ -50,6 +50,7 @@ dev = [
50
50
  "ruff>=0.14.13",
51
51
  ]
52
52
  ml = [
53
+ "hyper-models[ml]>=0.3.0",
53
54
  "torch>=2.9.1",
54
55
  "torchvision>=0.24.1",
55
56
  "timm>=1.0.0",
@@ -7,12 +7,16 @@ from . import ui as ui
7
7
  Dataset = _api.Dataset
8
8
  Session = _api.Session
9
9
  launch = _api.launch
10
+ register_provider = _api.register_provider
11
+ unregister_provider = _api.unregister_provider
10
12
  __version__ = _version.__version__
11
13
 
12
14
  __all__ = [
13
15
  "Dataset",
14
16
  "Session",
15
17
  "launch",
18
+ "register_provider",
19
+ "unregister_provider",
16
20
  "ui",
17
21
  "__version__",
18
22
  ]
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.6.0'
22
- __version_tuple__ = version_tuple = (0, 6, 0)
21
+ __version__ = version = '0.6.2'
22
+ __version_tuple__ = version_tuple = (0, 6, 2)
23
23
 
24
24
  __commit_id__ = commit_id = None