Skip to content

Conversation

@BioCam
Copy link
Collaborator

@BioCam BioCam commented Feb 1, 2026

No description provided.

@BioCam BioCam marked this pull request as draft February 3, 2026 22:25
@BioCam BioCam marked this pull request as ready for review February 3, 2026 22:25
@BioCam BioCam marked this pull request as draft February 3, 2026 22:25
BioCam and others added 4 commits February 3, 2026 22:28
…zation

- LiquidHandler: replace single `_resource_pickup` with `_resource_pickups` dict
  keyed by arm index, with backward-compatible property for arm 0
- LiquidHandler: only create head96 trackers when `core96_head_installed` is True
- LiquidHandler: serialize head96_state and arm_state (resource name, type, direction,
  dimensions) for downstream consumers (e.g. visualizer)
- LiquidHandler: register _state_updated callback on head/head96 trackers, and fire
  it on pick_up_resource / drop_resource
- LiquidHandler: guard pick_up_resource with RuntimeError if no arm installed
- Backends: add `num_arms` attribute to STARBackend, ChatterboxBackend,
  STARChatterboxBackend (configurable `iswap_installed` param)
- TipTracker: propagate state-update callback to tip's volume tracker on commit()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BioCam and others added 24 commits February 6, 2026 22:45
Resource names flow from the Python backend into innerHTML, allowing
vectors like <img src=x onerror=...> to execute arbitrary JS. Use
textContent + DOM element creation instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
_handle_state_update_callback wrote to _pending_state_updates from
arbitrary threads while _flush_state_updates read it on the event loop.
This could lose updates when a thread wrote to the dict between the
flush clearing it and resetting _flush_scheduled.

Move all dict writes onto the event loop via call_soon_threadsafe so
both enqueue and flush are single-threaded. Preserves batching behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
set_state was calling buildResourceTree() which destroys and recreates
the entire sidebar DOM on every state change (e.g. a single well volume
update). Use the existing updateSidepanelState() for each changed
resource instead, which does a targeted DOM update via querySelector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setup() was globally enabling tip and volume tracking, silently
overriding user settings. This is the caller's responsibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
inspect.signature was called for every method of every resource instance.
For a 96-well plate that's 97 × ~50 calls. Take the class as argument
instead and cache with lru_cache since all instances share the same methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The string-replace approach (': Infinity' -> ': "Infinity"') could
false-positive on resource names containing that substring. Use
allow_nan=False with a custom default handler instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The allow_nan=False + default handler approach doesn't work because
float('inf') is a native float type — json raises ValueError before
the default handler is ever called. Revert to the original string
replacement which handles this correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@BioCam BioCam marked this pull request as ready for review February 8, 2026 15:12
@BioCam BioCam requested a review from Copilot February 8, 2026 15:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the PyLabRobot Visualizer UI and backend event/serialization to support a richer interface (toolbars/sidepanel, source name + favicon, actuator panels) and reduce UI churn by batching state updates.

Changes:

  • Enrich resource serialization with public method signatures and recursively serialized children.
  • Add configurable visualizer header name/favicon and an optional “show actuators at start” event.
  • Update JS/HTML/CSS for a revamped layout (toolbars, sidepanel/tree, zoom controls) and more defensive state handling.

Reviewed changes

Copilot reviewed 5 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pylabrobot/visualizer/visualizer_tests.py Updates tests to match new serialization helper and additional startup event.
pylabrobot/visualizer/visualizer.py Adds method-enriched serialization, UI metadata injection (name/favicon), actuator startup event, and batched state updates.
pylabrobot/visualizer/vis.js Updates root rendering workflow, sidepanel/tree updates, snapshots on unassign, and handles new show_actuators event.
pylabrobot/visualizer/main.css Major UI styling additions for new navbar/toolbars/sidepanel and overlays.
pylabrobot/visualizer/index.html Adds favicon link, cache-busting query params, new toolbar/sidepanel layout, and new UI panels/controls.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@BioCam BioCam merged commit 8b9a20d into PyLabRobot:main Feb 8, 2026
10 checks passed
@BioCam BioCam deleted the visualizer_update branch February 8, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants