Version Packages - #9340
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryLow Risk Overview It removes the consumed Merging is what triggers the automated npm publish for these packages; the shipped user-facing scope is whatever those changelog bullets describe (Petrinaut ad-hoc scenarios, sweeps/WebGPU experiments, voice AI, HIR scenario execution, etc.). Reviewed by Cursor Bugbot for commit b880baf. Bugbot is set up for automated code reviews on this repo. Configure here. |
f88ffd0 to
aee8cd1
Compare
3319fdd to
3843181
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9340 +/- ##
=======================================
Coverage 60.89% 60.89%
=======================================
Files 1461 1461
Lines 146725 146725
Branches 6744 6744
=======================================
Hits 89343 89343
Misses 56264 56264
Partials 1118 1118
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
b2b99f3 to
6e2b92d
Compare
6f85461 to
20c2865
Compare
5c6340c to
51ffa88
Compare
ceaf230 to
a37f9ae
Compare
458523d to
8f1fa87
Compare
bd01409 to
f30f5cf
Compare
cc7059f to
a907d94
Compare
22c8f94 to
09f9498
Compare
6cda5da to
40b4e1d
Compare
a10b069 to
eb816f7
Compare
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@hashintel/ds-components@0.3.2
Patch Changes
Extract the contour plot into a
ContourSurfacecomponent shared by the sweep and optimization surfaces, decoupleSweepNavigatorfrom the experiments context, and add Storybook stories for each component's states. Sweep navigation is continuous: a point selection uses a single-thumb slider, slider moves commit during the drag, and charts keep their axes, grid and size while frames stream in.Slidertreats 0 as a real value, anduseElementSizefollows an element that mounts after the first render. (@kube, #9421)Optimization studies with two or more optimized numeric parameters gain a Surface section: a contour of the objective over two chosen parameters, computed locally against the study's frozen model, with the study's trials as markers. Sliders and clicks move the selected point, which refines with escalating batches.
SlideracceptsstepandonChangeEnd. (@kube, #9398)Add Breadcrumb component (@alex-e-leon, #9502)
@hashintel/petrinaut@0.0.20
Patch Changes
Arc weight labels sit on the Adaptive Bezier curve instead of floating at the straight-line midpoint between the arc's endpoints. (@kube, #9354)
The create-experiment drawer accepts an ad-hoc scenario when "No scenario" is selected: Initial State + Parameters defined inline compile through a generated, never-persisted scenario at experiment start. (@kube, #9288)
Fix three defects in the ad-hoc scenario form: the optimize bounds popover
ignored every press (Min, Max, Step and Scale were uneditable, and each press
dismissed it), a focused section painted over the sticky header of the section
hosting it, and the experiment drawer's computed initial state grew unbounded
instead of scrolling in its own region. (@kube, #9473)
The create-optimization drawer offers "Ad-hoc (define inline)": Initial State + Parameters with Optimize selections compile to a generated, never-persisted scenario whose generated parameters the optimization manifest binds to their optimize domains. (@kube, #9289)
Quick simulation runs an ad-hoc scenario when none is selected: a "Define initial state" drawer in the simulation settings panel edits token counts and values that compile through a generated, never-persisted scenario. (@kube, #9287)
Behind the new experimental "Ad-hoc scenarios" setting, the scenario creation form authors scenarios through the ad-hoc form: exposed Variables become the saved scenario's tunable parameters, and the definition persists as
initialState.type: "adhoc". (@kube, #9368)Add the ad-hoc scenarios user-guide page and register it with the in-app AI assistant's doc reader. (@kube, #9290)
The ad-hoc scenario form matches the ratified prototype: gutter-cycled row kinds (fixed → dynamic → count-optimized) with quiet count strips, shared columns with a wash and derived cells, a phantom trailing row, place totals, compact Variables blocks, and Monaco expression editors type-checked live through a new ad-hoc LSP session with diagnostics rendered on closed cells. (@kube)
Transition kernels, lambdas, and differential equations can now be written as a bare function body ending in
return, like metrics and scenario code:input(ortokensfor dynamics) andparametersare in scope ambiently, with full editor type checking and completions. Theexport default TransitionKernel(...)/Lambda(...)/Dynamics(...)module form is still accepted, and the editor picks the right checking mode per form. Default templates, built-in examples, and the AI assistant now use the bare form. Visualizers are unchanged. (@kube, #9370)The canvas renders centered on the net from its first frame, instead of jumping there after a first paint at the origin. Component instances grow with their port count so their ports have room, and auto-layout on import no longer depends on the compact/classic setting. (@kube, #9352)
Added a command registry for host-rendered command palettes:
createCommandRegistry()andcombineCommandRegistries()in core, andCommandRegistryProvider,useCommand(command, { when }),useCommands(), andformatShortcutKeys()in@hashintel/petrinaut/react. The editor registers its undo/redo, tool, auto-layout, search, and panel commands. Petrinaut ships no palette. (@kube, #9457)The experiment and optimization result drawers keep the summary, navigator and surface still at the top; only the step and metric lists scroll, with the step table's header pinned. (@kube, #9422)
Experiments can sweep scenario parameters. A Sweep toggle per numeric parameter defines the values, and the results drawer gains a navigator: only the selected combination computes, in escalating run batches that stream into the charts, and visited combinations keep their results. (@kube, #9093)
The WebGPU backend matches the CPU engine's stochastic semantics and frame numbering, streams metric frames per dispatch chunk, and runs range sweeps from a per-run parameter buffer. It sizes and calibrates metric histograms and typed-place buffers from the model and device instead of refusing or warning, and tiles experiments larger than the device's limits with bit-identical results. Sweep batch instantiation no longer blocks the main thread: scenario compilation is prepared once per experiment and per-run values travel as one typed-array plan. (@kube, #9454)
Distribution heatmaps in experiment metric charts render as a magma-coloured density image in one draw call, so they stay fast at high run counts. (@kube, #9450)
Swept parameters declare an interval instead of a value count, and the navigator becomes a range slider per parameter: the whole interval by default, resizable, collapsible to a point. A range selection samples the region and streams the merged distribution over it. The slider is a two-thumb range control local to the navigator, whose thumbs may coincide. (@kube, #9396)
Extract the contour plot into a
ContourSurfacecomponent shared by the sweep and optimization surfaces, decoupleSweepNavigatorfrom the experiments context, and add Storybook stories for each component's states. Sweep navigation is continuous: a point selection uses a single-thumb slider, slider moves commit during the drag, and charts keep their axes, grid and size while frames stream in.Slidertreats 0 as a real value, anduseElementSizefollows an element that mounts after the first render. (@kube, #9421)Optimization studies with two or more optimized numeric parameters gain a Surface section: a contour of the objective over two chosen parameters, computed locally against the study's frozen model, with the study's trials as markers. Sliders and clicks move the selected point, which refines with escalating batches.
SlideracceptsstepandonChangeEnd. (@kube, #9398)Run an experiment's runs in parallel across several Web Workers. (@kube, #9162)
An experiment used to run every one of its runs in a single worker, using one core however many the machine had. Runs are independent, so they now split across one worker per logical core (minus one, so the editor stays responsive), capped at the run count. Measured at ~4x on 8 shards on a 10-core machine.
Sharding cannot change what an experiment reports. Per-run seeds derive from the run's global index rather than its position within a shard, so run i gets the same seed whichever worker owns it, and each worker's per-frame statistics recombine through the metric accumulator monoids (
empty/merge). Output is byte-identical at every shard count while every shard still has an active run. A frame is only finalised once every still-running shard has reported it, with finished shards dropped from that watermark rather than blocking it — so once a whole shard's runs have ended early (for example by deadlock), that shard's completed runs stop contributing samples to later frames, where a single simulator would keep sampling their frozen state.Scalar metric frames now carry their pre-reduction accumulator state, because
frameValueis already reduced and a mean of means is not a mean.Hosts can cap or pin parallelism with
experimentShardCountonExperimentsProvider, orshardCountoncreateMonteCarloExperiment.Add a
navigationprop toPetrinaut: a router-neutral controller throughwhich the host can read and drive the app location (mode, Simulate section and
resource, scenario, subnet, selection, and creation drawers), making them real
browser history destinations. A creation drawer now layers over the record
already open instead of closing it, and the hamburger menu hides Layout on
a read-only net. (@kube, #9426)
Add an optional per-place token capacity. (@kube, #9177)
A place can now declare a maximum number of tokens it will hold, set from the place properties panel. Useful for supply-chain style models with finite storage. It also converts frames from growable to fixed-size, which is the precondition for a fixed-layout GPU or WASM path.
Capacity participates in transition enablement, following the standard Petri-net capacity constraint: a transition cannot fire if doing so would take any output place above its capacity. Output tokens are applied at the end of a frame, so the check accounts for what transitions earlier in the same frame have already committed. Several transitions feeding one capped place cannot collectively overflow it.
Deadlock detection includes the same check, so a net whose only remaining transitions are blocked by full output places is reported as deadlocked rather than stepping to
maxTimewith nothing happening.Nets without capacities are unaffected: the constraint tables are empty and the hot path skips them.
Reject net identifiers that collide with
Object.prototypemember names (__proto__,constructor, ...) at file import and before simulation, and store user-authored keys in prototype-free records. Place visualizer code now runs under the same sandbox hardening as scenario code. (@kube, #9222)Scenario code (parameter overrides, per-place expressions, code-mode initial state) now compiles through the HIR and runs in an interpreter: no
new Function, no sandbox. Out-of-subset code fails with positioned errors in the editor and at compile. Stricter than the old evaluator:==is strict, conditions and&&/||take booleans, unknown place names in code mode are errors, and array methods beyond.map/.reduce/.concatare unavailable.Array.from({ length: n }, fn)desugars torange(n).map(fn). (@kube, #9332)Range sweeps rotate each axis's low-discrepancy parameter draws by a seed-derived shift, so experiments with different seeds explore different value sequences. (@kube, #9435)
Sidebar list labels use the full row width and truncate with an ellipsis consistently; the row menu button only takes space while hovering the row or while its menu is open. (@kube, #9377)
Add generic host-rendered AI composer controls and a persistent inline Voice session, protected
active conversations, keyboard fallback, and one-answer buffering while the normal chat stream
settles. Add the provider-neutral
renderVoiceModecontract and exportPetrinautAiInputMode, withthe selected input mode and mode-change callback available to host-rendered Voice modes. Include
stable finalized-text submission, conversation identity, stop handling, schema-validated
interactive-tool text mapping, explicit separate-message targeting for corrections, and a
queue-aware voice submission path. Present text and voice through one transcript and composer whose
trailing action switches between waveform, Send, and Stop.
renderComposerControlremains asupported public seam for hosts that only need their own control beside the message box,
independently of Voice mode. Surface assistant request failures as error toasts instead of
transcript entries. (@kostandinang, #9355)
Render every live Voice surface from a session snapshot the host reports through
reportVoiceSessionState, so hosts describe their session while Petrinaut owns its chrome. Replacethe composer with a low-profile Voice dock -- a canvas ribbon of three travelling waves, one leading
and two trailing it more faintly, fading out at both ends, opening with the microphone while
listening and moving under its own power through the same drawing path while the assistant speaks,
near flat while neither holds the turn, and naming one phase at a time -- with an announced phase and
reduced-motion behavior. Curve the raw microphone level before it drives the waves, so an ordinary
speaking level is plainly visible rather than a flicker above the line and a raised voice still has
somewhere to go. Sample the level per animation frame rather than through React, so drawing costs no
re-renders, and ease it against the frame delta so it looks the same at any refresh rate. Hold spoken
turns out of the transcript until the session ends, then reveal them together under a turn-count
divider, while typed messages and interactive tools awaiting an answer stay visible throughout. Let a
per-session Show transcription in chat action write those turns into the conversation as they land
instead. Keep every session control -- transcription, the microphone toggle, Resume, Reconnect, and
End -- in the dock, leaving the canvas toolbar untouched. Add
setMicrophoneMutedto the Voice modecontrols and a
mutedsession phase, so muting stops capture without interrupting what the assistantis saying, unlike pausing. Surface voice recovery failures as toasts with privacy-safe diagnostic
references, and request one-time consent before the host starts the microphone. Mark persisted spoken
messages and the exact interactive-tool answer completed by Voice with an inline Voice chip ahead of
the words themselves.
End Voice mode before submitting typed text exactly once through the shared composer, preserving the
draft if handoff fails. Pause active media before the AI panel closes and reopen the mounted session
paused. Provisional transcription and Realtime audio remain ephemeral rather than becoming
persisted chat history.
Storybook gains a "With real optimizer" story that runs optimization studies against a local Petrinaut Optimizer service; start it with
turbo run dev --filter @hashintel/petrinaut -- --with-optimizer-service. (@kube, #9395)A sweep's range selection runs as one stochastic simulation over the ranges: every run draws its own value per ranged parameter, and the metric distribution over the region streams live.
ExperimentRequestcarries optional per-run overrides (runs), forwarded by the worker-pool backend and refused by the WebGPU backend. (@kube, #9419)Sweep compute is reused and pipelined: simulation workers persist across batches, surface cells sample in batched chunks in quad-tree order across the CPU pool, the navigator's selection streams first while the ladder pipelines its rungs, and one GPU backend (device, shader, calibration) with a small preview tile serves a session's batches. The surface reads a cell's value from the last sampled frame, so terminating nets fill it; charts mount their axes when the drawer opens and apply data once per animation frame. (@kube, #9474)
The frame inspector draws a frame's distribution as a canvas histogram with value and count axes. Distribution frames carry their bins' extent and heatmaps paint each bin across the rows it covers, so mixed strides no longer stripe, and streamed updates ease in instead of snapping. The sweep surface navigates by drag as well as click and marks the navigator's position, and the summary lists every batch computing in parallel. Parameter sweeps and the optimization surface are experimental settings, off by default. (@kube, #9478)
Sweeps with two or more swept parameters gain a Surface section: a contour of a metric's final value over two chosen parameters, filled in live on a background lane. Clicking it moves the navigator to the nearest combination. (@kube, #9369)
Add an experimental WebGPU compute backend for experiments, chosen per experiment behind a user setting. It runs the net's lowered HIR on the device, declines nets it cannot run so they fall back to the CPU, and agrees with the CPU in distribution rather than seed for seed. A Compilation panel, also behind a setting, shows what the compiler made of each condition, kernel and equation. (@kube, #9179)
Add the worksheet keyboard-flow primitives (
FocusStack,FocusRoot,useFocusGrid,useFocusStops): reusable arrow-key routing, per-group focus memory, and roving tab stops for panels composed of grids and controls. (@kube, #9411)Nets and optimization manifests can be imported and exported in YAML and JSON. (@kube, #9379)
Updated dependencies:
@hashintel/petrinaut-core@0.0.5
Patch Changes
Behind the new experimental "Ad-hoc scenarios" setting, the scenario creation form authors scenarios through the ad-hoc form: exposed Variables become the saved scenario's tunable parameters, and the definition persists as
initialState.type: "adhoc". (@kube, #9368)Add the ad-hoc scenarios user-guide page and register it with the in-app AI assistant's doc reader. (@kube, #9290)
Ad-hoc scenario synthesis: form state, deterministic
adhoc.*parameter names, synthesis to a generated code-mode scenario plus optimized fields with typed domains, the transform to optimization-manifest bindings, row-kind cycling and shared-column transitions, place totals, and an LSP session kind that type-checks every value expression. (@kube, #9284)Transition kernels, lambdas, and differential equations can now be written as a bare function body ending in
return, like metrics and scenario code:input(ortokensfor dynamics) andparametersare in scope ambiently, with full editor type checking and completions. Theexport default TransitionKernel(...)/Lambda(...)/Dynamics(...)module form is still accepted, and the editor picks the right checking mode per form. Default templates, built-in examples, and the AI assistant now use the bare form. Visualizers are unchanged. (@kube, #9370)Added a command registry for host-rendered command palettes:
createCommandRegistry()andcombineCommandRegistries()in core, andCommandRegistryProvider,useCommand(command, { when }),useCommands(), andformatShortcutKeys()in@hashintel/petrinaut/react. The editor registers its undo/redo, tool, auto-layout, search, and panel commands. Petrinaut ships no palette. (@kube, #9457)The layout module exports the canvas geometry: render node dimensions (
compactNodeDimensions,classicNodeDimensions,getComponentInstanceHeight), net bounds (getBoundsOfCenteredBoxes) and zoom limits (getMinZoomForBounds,ZOOM_PADDING).layoutNodeDimensionsis now derived from the render dimensions instead of maintained by hand. (@kube, #9352)Add the
@hashintel/petrinaut-core/experimentsentry point: anExperimentBackendinterface, a worker-pool implementation of it, andselectExperimentBackend, which walks backends in preference order and records every refusal. (@kube, #9178)createJsonDocHandleacceptsSDCPNInput, a loose authoring variant ofSDCPN: extension fields may be omitted and are filled with plain-net defaults by the newnormalizeSDCPNexport.SDCPNInputand its member types are exported from the package root. (@kube, #8926)The WebGPU backend matches the CPU engine's stochastic semantics and frame numbering, streams metric frames per dispatch chunk, and runs range sweeps from a per-run parameter buffer. It sizes and calibrates metric histograms and typed-place buffers from the model and device instead of refusing or warning, and tiles experiments larger than the device's limits with bit-identical results. Sweep batch instantiation no longer blocks the main thread: scenario compilation is prepared once per experiment and per-run values travel as one typed-array plan. (@kube, #9454)
Weighted-arc token combinations enumerate lazily in the same lexicographic order, so a transition with a weight-2 coloured input arc no longer materialises every combination per frame. Trajectories are unchanged for every seed. (@kube, #9386)
Run an experiment's runs in parallel across several Web Workers. (@kube, #9162)
An experiment used to run every one of its runs in a single worker, using one core however many the machine had. Runs are independent, so they now split across one worker per logical core (minus one, so the editor stays responsive), capped at the run count. Measured at ~4x on 8 shards on a 10-core machine.
Sharding cannot change what an experiment reports. Per-run seeds derive from the run's global index rather than its position within a shard, so run i gets the same seed whichever worker owns it, and each worker's per-frame statistics recombine through the metric accumulator monoids (
empty/merge). Output is byte-identical at every shard count while every shard still has an active run. A frame is only finalised once every still-running shard has reported it, with finished shards dropped from that watermark rather than blocking it — so once a whole shard's runs have ended early (for example by deadlock), that shard's completed runs stop contributing samples to later frames, where a single simulator would keep sampling their frozen state.Scalar metric frames now carry their pre-reduction accumulator state, because
frameValueis already reduced and a mean of means is not a mean.Hosts can cap or pin parallelism with
experimentShardCountonExperimentsProvider, orshardCountoncreateMonteCarloExperiment.Expose the selection vocabulary as data:
selectionItemTypesandcanonicalizeSelectionare available from a dependency-free@hashintel/petrinaut-core/selectionentry, so hosts can validate and orderselection coming from a URL or an HTTP request without pulling the model or any
React code. (@kube, #9426)
Add an optional per-place token capacity. (@kube, #9177)
A place can now declare a maximum number of tokens it will hold, set from the place properties panel. Useful for supply-chain style models with finite storage. It also converts frames from growable to fixed-size, which is the precondition for a fixed-layout GPU or WASM path.
Capacity participates in transition enablement, following the standard Petri-net capacity constraint: a transition cannot fire if doing so would take any output place above its capacity. Output tokens are applied at the end of a frame, so the check accounts for what transitions earlier in the same frame have already committed. Several transitions feeding one capped place cannot collectively overflow it.
Deadlock detection includes the same check, so a net whose only remaining transitions are blocked by full output places is reported as deadlocked rather than stepping to
maxTimewith nothing happening.Nets without capacities are unaffected: the constraint tables are empty and the hot path skips them.
Reject net identifiers that collide with
Object.prototypemember names (__proto__,constructor, ...) at file import and before simulation, and store user-authored keys in prototype-free records. Place visualizer code now runs under the same sandbox hardening as scenario code. (@kube, #9222)Scenario code (parameter overrides, per-place expressions, code-mode initial state) now compiles through the HIR and runs in an interpreter: no
new Function, no sandbox. Out-of-subset code fails with positioned errors in the editor and at compile. Stricter than the old evaluator:==is strict, conditions and&&/||take booleans, unknown place names in code mode are errors, and array methods beyond.map/.reduce/.concatare unavailable.Array.from({ length: n }, fn)desugars torange(n).map(fn). (@kube, #9332)A sweep's range selection runs as one stochastic simulation over the ranges: every run draws its own value per ranged parameter, and the metric distribution over the region streams live.
ExperimentRequestcarries optional per-run overrides (runs), forwarded by the worker-pool backend and refused by the WebGPU backend. (@kube, #9419)Sweep compute is reused and pipelined: simulation workers persist across batches, surface cells sample in batched chunks in quad-tree order across the CPU pool, the navigator's selection streams first while the ladder pipelines its rungs, and one GPU backend (device, shader, calibration) with a small preview tile serves a session's batches. The surface reads a cell's value from the last sampled frame, so terminating nets fill it; charts mount their axes when the drawer opens and apply data once per animation frame. (@kube, #9474)
The frame inspector draws a frame's distribution as a canvas histogram with value and count axes. Distribution frames carry their bins' extent and heatmaps paint each bin across the rows it covers, so mixed strides no longer stripe, and streamed updates ease in instead of snapping. The sweep surface navigates by drag as well as click and marks the navigator's position, and the summary lists every batch computing in parallel. Parameter sweeps and the optimization surface are experimental settings, off by default. (@kube, #9478)
Transitions whose lambda reads no input tokens skip combination enumeration and evaluate the lambda once against the first tokens in place order. Trajectories are unchanged for every seed. (@kube, #9389)
Optimization trials run their seeded replicates in parallel as one sharded experiment. The Monte Carlo worker protocol attaches to any thread runtime, and the CLI's
--threads <n>bounds the workers, defaulting to one per core minus one. (@kube, #9358)Add an experimental WebGPU compute backend for experiments, chosen per experiment behind a user setting. It runs the net's lowered HIR on the device, declines nets it cannot run so they fall back to the CPU, and agrees with the CPU in distribution rather than seed for seed. A Compilation panel, also behind a setting, shows what the compiler made of each condition, kernel and equation. (@kube, #9179)
Nets and optimization manifests can be imported and exported in YAML and JSON. (@kube, #9379)