Skip to content

FE-778: Offer Sweep toggles on ad-hoc scenarios in the experiment drawer - #9624

Merged
kube merged 8 commits into
mainfrom
claude/fe-778-adhoc-experiment-sweeps
Sep 9, 2026
Merged

FE-778: Offer Sweep toggles on ad-hoc scenarios in the experiment drawer#9624
kube merged 8 commits into
mainfrom
claude/fe-778-adhoc-experiment-sweeps

Conversation

@kube

@kube kube commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Important

Experimental
Behind the Ad-hoc scenarios and Parameter sweeps feature flags.

Summary

Before this PR, the create-experiment drawer offered a Sweep toggle on the classic scenario parameter rows only. With ad-hoc scenarios enabled the drawer shows every scenario through the ad-hoc form, and the form had no such toggle: neither an inline definition nor a saved scenario shown through it could be swept.

The form gains a sweep selection. Every numeric value carries a Sweep toggle that opens Min and Max bounds, a saved scenario's numeric parameters carry the same toggle in the run-mode rows, and each selection becomes a swept parameter of the experiment. Generated parameters show under the value's path in the sweep navigator and the surface.

9624.mp4

Links

Changes

Ad-hoc form

  • sweep joins the form's selections

    Numeric values, Variables and Parameters carry a Sweep toggle; booleans and text carry none.
    The bounds slab shows Min and Max only, no Step and no Scale.

  • Run-mode scenario parameter rows carry the toggle

    A saved scenario shown through the form sweeps its numeric parameters like the classic rows do.

  • Gutter menu names the row kind after the consumer

    "Swept count" in the experiment drawer, "Optimized count" in the optimization drawer.

Experiments

  • Ad-hoc selections become sweep axes

    compileExperimentScenario synthesizes the definition with its selections, and buildAdHocSweepAxes turns each generated parameter's domain into an axis.
    adHocSweeps on the input says whether selections count; off, the definition runs at its fixed values.

  • Axes carry a label

    Navigator, surface and summary show Queue › count for adhoc_count_Queue.

  • Run-mode form reports ranges and fixed values through one path

    scenarioRunInputs turns a swept Variable into a range from its resolved bounds and every other one into a fixed value.

Review fixes

  • A type change drops a Sweep the new type cannot carry

    A swept Variable turned boolean kept its selection with no toggle left to clear it, and the run refused with "boolean values cannot be swept".
    The type change and the toggle-off apply as one action batch, so undo restores both together.

  • A selection already on a Variable keeps its toggle whatever the type

    A boolean carrying a Sweep shows the toggle so the definition can be brought back to something that runs.

  • Run mode shows no Sweep toggles on the computed net parameters

    The Computed state preview is derived by the host; a toggle there reverted on the next render.

  • Run-mode form takes the experiment's inputs, ranges included

    A reseed rebuilds a swept parameter's Sweep from its range instead of dropping it.
    The Computed state previews a swept parameter at the start of its range, the first combination the sweep runs, and its notice names the value.

Test coverage

  • parameter-grid.test.ts:

    Ad-hoc axes from integer and continuous domains, error naming the value's label, boolean refusal.

  • provider.test.tsx:

    An ad-hoc count selection compiles to a labelled axis and a swept compiler; the flag off runs the fixed value.

  • experiment-scenario-inputs.test.ts:

    Fixed values, a range from resolved bounds, no range for a bound that does not resolve.

  • ad-hoc-scenario-form.test.tsx, create-experiment-drawer.test.tsx:

    Sweep toggles on numeric values only, in authoring and run mode, and only with both settings on.

  • ad-hoc-scenario-form.test.tsx, review fixes:

    A type change to boolean turns the Sweep off as one undo step, a Sweep on a boolean stays clearable, run mode offers no Sweep on net parameters.

  • experiment-scenario-run.test.tsx, review fixes:

    A range input seeds the Variable's Sweep and previews the range start with a notice.

How to test

  • Open Petrinaut preview on Vercel
  • Menu > Load example > SIR Epidemic Model
  • Viewport controls > Settings > General > Ad-hoc scenarios
  • Viewport controls > Settings > Simulation > Parameter sweeps
  • Simulate > Experiments > Create experiment
  • Scenario > No scenario, open a place's count cell

    Expect a Sweep toggle under the editor

  • Turn Sweep on, set Min 10 and Max 200

    Expect the summary line to name the swept value

  • Add a metric, press Run

    Expect a Parameters strip with a slider labelled by the place's path

  • Scenario > Seasonal Flu

    Expect a Sweep toggle on each numeric scenario parameter row

… open

The form's language session synced to the worker on every state identity
change; run-mode hosts rebuild an equal state per render, and each sync
republished diagnostics, which re-rendered the hosts: a loop that held the
canvas at 9 fps for as long as Simulation Settings showed a scenario. The
session now follows the definition's content.

The simulation provider was excluded from React Compiler by a throw inside
initialize's try/catch, so every render handed out new identities for all
derived values; the compile-or-throw step moved to a helper. The worker
reuses the net's own diagnostics across session-only syncs, and the client
drops publishes that change nothing. Run-mode hosts reseed on scenario
content, not object identity, so a node drag no longer remounts the form.
Place totals and slot labels index the state once per render.
@kube kube self-assigned this Sep 9, 2026
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 9, 2026 3:14pm UTC
petrinaut Ready Ready Preview Sep 9, 2026 3:14pm UTC
petrinaut-docs Ready Ready Preview Sep 9, 2026 3:14pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 9, 2026 3:14pm UTC

Request Review

@cursor

cursor Bot commented Sep 9, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches experiment compilation, sweep axis building, and ad-hoc form state; incorrect bounds or synthesis could block runs or mis-label sweep axes, but behavior is gated behind two experimental flags and covered by new tests.

Overview
Adds parameter sweeps to ad-hoc scenarios in the create-experiment flow when Ad-hoc scenarios and Parameter sweeps are both enabled.

The ad-hoc form gains a sweep selection: numeric slots get a Sweep toggle with Min/Max only (no Step/Scale), mirroring optimize placement. Saved scenarios in run mode get the same toggle on numeric scenario parameters; gutter copy uses Swept count in experiments.

Experiment creation passes adHocSweeps and compileExperimentScenario synthesizes sweep selections via synthesizeAdHocOptimization, builds axes with buildAdHocSweepAxes, and runs sweep sessions from those axes. Swept ad-hoc parameters show human paths (Queue › count) in the navigator, surface, and summary via optional axis label / axisDisplayName.

ExperimentScenarioRun now syncs full parameter inputs (fixed + range), reseeds sweep state from ranges, and previews computed state at each swept parameter’s range minimum. Form history supports batched dispatches so changing a variable type clears an invalid sweep in one undo step.

Docs describe sweep selections on ad-hoc forms and experiment configuration.

Reviewed by Cursor Bugbot for commit e67244d. Bugbot is set up for automated code reviews on this repo. Configure here.

@kube
kube added this pull request to stack #9629 September 9, 2026 12:27

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4070dcb. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Three moderate issues affect sweep controls, invalid retained selections, and computed-state preview accuracy.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds parameter sweep support for ad-hoc and saved scenarios in Petrinaut’s experiment drawer, behind the relevant feature flags.

Changes:

  • Adds numeric Sweep controls and range handling.
  • Compiles ad-hoc selections into labeled sweep axes.
  • Updates experiment UI, tests, documentation, and release metadata.

Unresolved findings:

  • Moderate: Computed-state parameters incorrectly expose nonfunctional Sweep toggles.
  • Moderate: Changing a swept variable to a nonnumeric type can leave an uncleared selection that prevents execution.
  • Moderate: Computed-state previews use defaults rather than values represented by active sweep ranges.
File summaries
File Description
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/shared/surface-frame.tsx Supports labeled axis options.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/sweep-surface.tsx Uses friendly labels in sweep readouts.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/sweep-navigator.tsx Displays friendly axis labels.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/experiment-scenario-run.tsx Enables saved-scenario sweep inputs.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/experiment-scenario-run.test.tsx Updates run-component tests.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/experiment-scenario-inputs.ts Converts run-form values into fixed or ranged inputs.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/experiment-scenario-inputs.test.ts Tests fixed and ranged input conversion.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.tsx Integrates sweep controls and summaries.
libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.test.tsx Tests feature-flagged drawer controls.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/variable-rows.tsx Adds numeric variable Sweep toggles.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/value-editor.tsx Displays Min and Max sweep bounds.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/token-table.tsx Adds consumer-specific row actions.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/scenario-parameter-rows.tsx Adds saved-scenario Sweep toggles.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/parameter-rows.tsx Adds parameter Sweep toggles.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/form-context.ts Defines sweep selection behavior.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/ad-hoc-scenario-form.tsx Supports the sweep form consumer mode.
libs/@hashintel/petrinaut/src/ui/components/ad-hoc-scenario-form/ad-hoc-scenario-form.test.tsx Tests numeric-only sweep controls.
libs/@hashintel/petrinaut/src/react/experiments/provider/create-experiment.ts Compiles ad-hoc sweep scenarios.
libs/@hashintel/petrinaut/src/react/experiments/provider.tsx Starts sessions with compiled sweep axes.
libs/@hashintel/petrinaut/src/react/experiments/provider.test.tsx Tests ad-hoc sweep compilation.
libs/@hashintel/petrinaut/src/react/experiments/parameter-grid.ts Builds labeled ad-hoc sweep axes.
libs/@hashintel/petrinaut/src/react/experiments/parameter-grid.test.ts Tests axis generation and validation.
libs/@hashintel/petrinaut/src/react/experiments/context.ts Extends experiment creation input.
libs/@hashintel/petrinaut/docs/experiments.md Documents experiment sweep behavior.
libs/@hashintel/petrinaut/docs/ad-hoc-scenarios.md Documents ad-hoc sweep selections.
.changeset/adhoc-experiment-sweeps.md Records the Petrinaut release change.
Review details
  • Files reviewed: 26/26 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

kube added 5 commits September 9, 2026 17:01
With Parameter sweeps on, the ad-hoc form in the create-experiment drawer
renders in a sweep selection: every numeric value slot carries a Sweep
toggle that opens Min and Max bounds, and a saved scenario shown through
the form offers the same toggle on each numeric scenario parameter, as the
classic rows do. Each selection synthesizes to a generated scenario
parameter whose domain becomes a sweep axis, labelled with the value's
path in the navigator and the surface.
The summary line that names the swept parameters rendered only under the
classic scenario rows; the ad-hoc form and a saved scenario shown through
it get the same line.
@kube
kube added this pull request to the merge queue Sep 9, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue because a pull request earlier in the stack was removed Sep 9, 2026
@kube
kube added this pull request to the merge queue Sep 9, 2026
Base automatically changed from claude/fe-778-adhoc-form-render-performance to main September 9, 2026 17:21
Merged via the queue into main with commit 096405c Sep 9, 2026
88 of 99 checks passed
@kube
kube deleted the claude/fe-778-adhoc-experiment-sweeps branch September 9, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

3 participants