diff --git a/.github/workflows/webr-repo.yaml b/.github/workflows/webr-repo.yaml index cce5a97..0b4baec 100644 --- a/.github/workflows/webr-repo.yaml +++ b/.github/workflows/webr-repo.yaml @@ -24,6 +24,10 @@ on: branches: [main, master] pull_request: branches: [main, master] + # Match the pkgdown workflow's release trigger so publishing a release rebuilds + # the wasm binary too, keeping it in sync with the docs that install from it. + release: + types: [published] workflow_dispatch: name: webr-repo.yaml diff --git a/NEWS.md b/NEWS.md index eb3808f..108f171 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # LAGOtrials 1.1.0 -* Added a live in-browser demo to the documentation site (`live-demo.html`) that runs the real package client-side with webR (R compiled to WebAssembly), so anyone can try `lago_optimization()` with no installation. A GitHub Actions workflow builds the package to WebAssembly with the rwasm toolchain and publishes it as a small CRAN-like repository alongside the site. +* Added a live in-browser demo to the documentation site (`live-demo.html`) that runs the real package client-side with webR (R compiled to WebAssembly), so anyone can try `lago_optimization()` with no installation, plus an interactive playground (`playground.html`) where you pick a bundled dataset or upload a CSV, configure the model with sliders and toggles, and see the recommendation drawn with the package's own D3 charts alongside a copy-pasteable R snippet. A GitHub Actions workflow builds the package to WebAssembly with the rwasm toolchain and publishes it as a small CRAN-like repository alongside the site. * `lago_report()` now renders an interactive HTML dashboard: the confidence set is a hover-enabled D3 plot (a scatter for two components, a strip for one) with the recommended intervention highlighted, and each intervention component gets interactive total-cost and marginal-cost curves. The report stays a single self-contained offline file (D3 is inlined, no CDN or server) and its API is unchanged; rendering now also uses `jsonlite` (a new Suggests). * Added an MCP (Model Context Protocol) server to the Python package (`python -m lago.mcp_server`) that exposes `optimize` and `sensitivity` as tools any MCP-aware AI agent can call, plus a `sensitivity()` function in the Python wrapper. * Added `lago_sensitivity()`, which re-runs an optimization across a sweep of one input (an outcome or power goal, or a `"cost_multiplier"` that scales all costs) and reports how the recommended intervention, its cost, and the estimated outcome move, with `print()` and `plot()` methods. diff --git a/README.md b/README.md index 92cd0b1..4e1e3ed 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The LAGOtrials R package bridges the gap between theoretical advances in Learn-A 3) estimating the optimal intervention based on data from all stages, 4) calculating the 95% confidence sets for the recommended interventions and the optimal interventions. -> **Try it in your browser, no installation needed:** the [live demo](https://correspondmerchant.github.io/LAGO-R-Package/live-demo.html) runs the real `LAGOtrials` package client-side with [webR](https://docs.r-wasm.org/webr/latest/) (R compiled to WebAssembly). Edit the example and press Run. +> **Try it in your browser, no installation needed:** the [live demo](https://correspondmerchant.github.io/LAGO-R-Package/live-demo.html) runs the real `LAGOtrials` package client-side with [webR](https://docs.r-wasm.org/webr/latest/) (R compiled to WebAssembly) — edit the example and press Run. For a guided version, the [playground](https://correspondmerchant.github.io/LAGO-R-Package/playground.html) lets you pick a bundled dataset or upload your own CSV, configure the model with sliders and toggles, and see the recommendation as interactive charts plus a copy-pasteable R snippet. ## Table of Contents 1. [How to install the R package](#how-to-install-the-r-package) @@ -42,7 +42,7 @@ The LAGOtrials R package bridges the gap between theoretical advances in Learn-A ``` - Method 2: Clone this repo into RStudio, you can follow the directions provided [in this video](https://www.youtube.com/watch?v=NInwldFZgwA&t=275s). -Not ready to install? Try the package in your browser on the [live demo page](https://correspondmerchant.github.io/LAGO-R-Package/live-demo.html). +Not ready to install? Try the package in your browser on the [live demo page](https://correspondmerchant.github.io/LAGO-R-Package/live-demo.html), or design an optimization interactively with the [guided playground](https://correspondmerchant.github.io/LAGO-R-Package/playground.html). ## The main functions The LAGOtrials R package has four user-facing functions `lago_optimization()`, `lago_sensitivity()`, `visualize_cost()`, and `lago_report()`. diff --git a/_pkgdown.yml b/_pkgdown.yml index 523db40..e275f16 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -9,12 +9,15 @@ authors: navbar: structure: - left: [reference, articles, news, demo] + left: [reference, articles, news, demo, playground] right: [search, github] components: demo: text: Live demo href: live-demo.html + playground: + text: Playground + href: playground.html news: releases: diff --git a/pkgdown/assets/live-demo.html b/pkgdown/assets/live-demo.html index a8b5157..77df462 100644 --- a/pkgdown/assets/live-demo.html +++ b/pkgdown/assets/live-demo.html @@ -78,6 +78,7 @@

LAGOtrials — live demo

@@ -92,7 +93,7 @@

LAGOtrials — live demo

so give it a moment.

-
Starting webR…
+
Starting webR…
diff --git a/pkgdown/assets/playground.html b/pkgdown/assets/playground.html new file mode 100644 index 0000000..50ccce9 --- /dev/null +++ b/pkgdown/assets/playground.html @@ -0,0 +1,709 @@ + + + + + + LAGOtrials playground + + + + +
+
+

LAGOtrials — playground

+ +
+
+ +
+

+ Design a LAGO optimization interactively, in your browser, with no install. Pick a bundled dataset or upload your + own CSV, choose the outcome and intervention components, set the bounds, per-unit costs and outcome goal, then press + Run. The recommendation is drawn with the package's own interactive + webR-powered charts. +

+ +
Starting webR…
+

First load downloads R and the package (tens of MB) once and can take up to a minute; after that, runs are quick.

+ +
+

1. Data

+
+
+ + +
+
+ +
Drop a .csv here, or click to choose
+ +

Comma-separated with a header row; numeric columns become the outcome and component choices.

+
+
+

+
+ +
+

2. Model

+
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ +
+ + +
+
+
+ +
+
+
+ +
+ + + +
+ +
+
+

R code for this configuration

+ +
+

Paste this into R (after library(LAGOtrials)) to reproduce the run.

+
# choose an outcome and at least one intervention component
+
+ +

Result

+

+    
+
+ +

+ webR runs a WebAssembly build of R (4.6.0) entirely client-side; nothing you load or type leaves your browser. The + confidence-set plot is drawn for one- or two-component interventions (three or more still get the cost curves and the + full console summary). This playground exposes the common options; for the rest — a power goal, center + characteristics and fixed effects, clustering (icc), a custom GLM family/link, and more — call + lago_optimization() in R (copy the snippet above as a starting point). See the + package documentation for the complete API. +

+
+ + + + diff --git a/tests/js/test-webr-demo.js b/tests/js/test-webr-demo.js index 28ebc03..6ec926c 100644 --- a/tests/js/test-webr-demo.js +++ b/tests/js/test-webr-demo.js @@ -1,13 +1,14 @@ -// Guards the live webR demo wiring (pkgdown/assets/live-demo.html) against the -// wasm-repo build workflow (.github/workflows/webr-repo.yaml). +// Guards both webR pages' wiring (pkgdown/assets/live-demo.html and +// pkgdown/assets/playground.html) against the wasm-repo build workflow +// (.github/workflows/webr-repo.yaml). // // Run with: node tests/js/test-webr-demo.js // // A wasm package binary built against one webR ABI will not load in a different -// webR runtime, so the webR version the page loads from the CDN MUST equal the +// webR runtime, so the webR version each page loads from the CDN MUST equal the // webR Docker image the binary is built with. This test also checks that the -// package repository URL the page installs from matches the folder the workflow -// deploys to, and that the page actually installs LAGOtrials. These are the +// package repository URL each page installs from matches the folder the workflow +// deploys to, and that each page actually installs LAGOtrials. These are the // wiring mistakes that would silently break the demo without any R/JS error at // build time. @@ -20,11 +21,6 @@ var workflow = fs.readFileSync( path.join(root, ".github/workflows/webr-repo.yaml"), "utf8" ); -var page = fs.readFileSync( - path.join(root, "pkgdown/assets/live-demo.html"), - "utf8" -); - var passed = 0; function check(name, cond) { if (!cond) { @@ -40,36 +36,39 @@ var buildMatch = workflow.match(/ghcr\.io\/r-wasm\/webr:v(\d+\.\d+\.\d+)/); check("workflow pins a webr-image version", !!buildMatch); var buildVersion = buildMatch && buildMatch[1]; -// webR version the page loads: the WEBR_VERSION constant and the CDN import URL. -var constMatch = page.match(/WEBR_VERSION\s*=\s*"(\d+\.\d+\.\d+)"/); -check("page declares a WEBR_VERSION", !!constMatch); -var pageVersion = constMatch && constMatch[1]; +// The repo folder the workflow deploys to (target-folder). +var targetMatch = workflow.match(/target-folder:\s*([^\s#]+)/); +check("workflow declares a deploy target-folder", !!targetMatch); +var targetFolder = targetMatch && targetMatch[1].trim(); -// The CDN import URL is built from WEBR_VERSION, so pinning is single-sourced; -// assert the import references that constant rather than a hard-coded version. -check( - "page imports webr.mjs pinned to WEBR_VERSION", - page.indexOf("webr.r-wasm.org/v${WEBR_VERSION}/webr.mjs") !== -1 -); +// Both webR pages must agree with the build on the ABI-critical version and +// install LAGOtrials from the deployed repo. +["live-demo.html", "playground.html"].forEach(function (name) { + var page = fs.readFileSync(path.join(root, "pkgdown/assets", name), "utf8"); -// The ABI lock: build image version == page runtime version. -check( - "build webR version (" + buildVersion + ") == page webR version (" + pageVersion + ")", - buildVersion === pageVersion -); + var constMatch = page.match(/WEBR_VERSION\s*=\s*"(\d+\.\d+\.\d+)"/); + check(name + ": declares a WEBR_VERSION", !!constMatch); + var pageVersion = constMatch && constMatch[1]; -// The page installs LAGOtrials. -check("page installs LAGOtrials", /webr::install\("LAGOtrials"/.test(page)); + // The CDN import URL is built from WEBR_VERSION, so pinning is single-sourced. + check( + name + ": imports webr.mjs pinned to WEBR_VERSION", + page.indexOf("webr.r-wasm.org/v${WEBR_VERSION}/webr.mjs") !== -1 + ); -// The repo folder the workflow deploys to (target-folder) is the folder the -// page installs from. -var targetMatch = workflow.match(/target-folder:\s*([^\s#]+)/); -check("workflow declares a deploy target-folder", !!targetMatch); -var targetFolder = targetMatch && targetMatch[1].trim(); -check( - "page install URL points at the deployed /" + targetFolder + " repo", - page.indexOf("/" + targetFolder) !== -1 && - /correspondmerchant\.github\.io\/LAGO-R-Package\//.test(page) -); + // The ABI lock: build image version == page runtime version. + check( + name + ": webR version (" + pageVersion + ") == build (" + buildVersion + ")", + buildVersion === pageVersion + ); + + check(name + ": installs LAGOtrials", /webr::install\("LAGOtrials"/.test(page)); + + check( + name + ": install URL points at the deployed /" + targetFolder + " repo", + page.indexOf("/" + targetFolder) !== -1 && + /correspondmerchant\.github\.io\/LAGO-R-Package\//.test(page) + ); +}); console.log("\nAll " + passed + " webR demo wiring assertions passed.");