diff --git a/README.md b/README.md
index 544852672..63efa0ccc 100644
--- a/README.md
+++ b/README.md
@@ -37,23 +37,19 @@ state, the run stops for review.
## Try it locally
OpenAdapt requires Python 3.10–3.12. Easiest install (creates its own
-environment and includes the browser capability for the bundled tutorial):
+environment):
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
curl -fsSL https://raw.githubusercontent.com/OpenAdaptAI/openadapt-flow/main/scripts/install.sh | sh
```
-Manual path with pip — install the browser capability for the bundled
-tutorial:
+Manual path with pip:
```bash
-python -m pip install --upgrade 'openadapt[browser]'
+python -m pip install --upgrade openadapt
```
-On Windows `cmd.exe`, use double quotes:
-`python -m pip install --upgrade "openadapt[browser]"`.
-
Run the complete bundled tutorial with one command. It needs no account,
target application, API key, or operating-system automation permissions:
@@ -89,8 +85,9 @@ effect verifiers, fault cases, and deployment policy. Continue with the
## Record your workflow
-The browser path is an explicit capability, so native and remote-only installs
-do not carry the Playwright driver:
+The base package includes the Playwright driver for the bundled tutorial.
+Chromium downloads only when the first browser action starts. Native and
+remote workflows do not start or download Chromium:
```bash
openadapt flow record --backend web --url https://your-app.example --out rec
diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md
index 7a17d6d2a..6fd0183d3 100644
--- a/docs/getting-started/installation.md
+++ b/docs/getting-started/installation.md
@@ -7,19 +7,12 @@
OpenAdapt supports Python 3.10, 3.11, and 3.12. Use a virtual environment for
an isolated install.
-## Browser tutorial
+## Install and run the browser tutorial
-Install the launcher with the browser capability:
+Install the launcher:
```bash
-python -m pip install --upgrade 'openadapt[browser]'
-openadapt quickstart
-```
-
-On Windows `cmd.exe`, use double quotes:
-
-```bat
-python -m pip install --upgrade "openadapt[browser]"
+python -m pip install --upgrade openadapt
openadapt quickstart
```
@@ -34,8 +27,9 @@ profile with no model or Cloud call.
## Capability-specific installs
-The base install includes the launcher and the Flow engine. Add only the
-capabilities that the target workflow needs:
+The base install includes the launcher, the Flow engine, and the Playwright
+driver for the browser tutorial. Chromium downloads only on the first browser
+action. Add the applicable capability for a native or remote workflow:
```bash
python -m pip install 'openadapt[capture]' # local human demonstration
diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md
index aaa0cc06b..caa7d3c13 100644
--- a/docs/getting-started/quickstart.md
+++ b/docs/getting-started/quickstart.md
@@ -8,12 +8,10 @@
Use Python 3.10, 3.11, or 3.12:
```bash
-python -m pip install --upgrade 'openadapt[browser]'
+python -m pip install --upgrade openadapt
openadapt quickstart
```
-On Windows `cmd.exe`, use double quotes around the install target.
-
The command runs one complete local lifecycle against synthetic MockMed data:
1. It records a demonstrated browser workflow.
diff --git a/docs/packages/index.md b/docs/packages/index.md
index 3caf008f2..cff6a90db 100644
--- a/docs/packages/index.md
+++ b/docs/packages/index.md
@@ -11,10 +11,10 @@ cockpit, privacy tools, and optional managed control plane.
| `openadapt-privacy` | Local privacy and sanitization support | `pip install 'openadapt[privacy]'` |
| `openadapt-desktop` | Beta visual authoring and operator application | [Download an installer](https://openadapt.ai/download) |
-Install the browser tutorial path:
+Install the launcher and run the browser tutorial:
```bash
-python -m pip install --upgrade 'openadapt[browser]'
+python -m pip install --upgrade openadapt
openadapt quickstart
```
diff --git a/docs/platform-compatibility-report.md b/docs/platform-compatibility-report.md
index 53dedf389..c4318fe23 100644
--- a/docs/platform-compatibility-report.md
+++ b/docs/platform-compatibility-report.md
@@ -2,7 +2,7 @@
-- Generated: `2026-08-22T22:03:24+00:00`
+- Generated: `2026-08-26T14:19:29+00:00`
- Release channel: **beta**
- Selection: `latest-published`
- Compatibility: **dependency-compatible**
@@ -13,7 +13,7 @@
| Role | Package | Version | Release source reference | Published artifacts |
|---|---|---:|---|---|
| launcher | `openadapt` | `1.14.0` | [`v1.14.0`](https://github.com/OpenAdaptAI/OpenAdapt/tree/v1.14.0)
commit `b9e096535224e0cb4b62d89f097a6b09c318bfe5`
tree `27a7d4ed881d97cf58aa7d1d83a912e52eecc124` | `openadapt-1.14.0-py3-none-any.whl` `ac79ccb3b502f6a6c309fd05fa965ed874bee3470e45cf9ac919ef4df6c0bc8f`
`openadapt-1.14.0.tar.gz` `0a5456faa6769a2186cd653050134bb3c91cb202e9a147fcd611b0671c52370f` |
-| flow | `openadapt-flow` | `1.32.0` | [`v1.32.0`](https://github.com/OpenAdaptAI/openadapt-flow/tree/v1.32.0)
commit `d1b054c718d60465fb8a2e1853e6a84c7f26dec2`
tree `191b54985409034933b57e10fd08a17739277a47` | `openadapt_flow-1.32.0-py3-none-any.whl` `d58dcf8b7e54c8a45199db4390a588dc261bb754c5ab2af0fdb540e44cb6bb8a`
`openadapt_flow-1.32.0.tar.gz` `c3125f16c1b12420dff4a3af4c3d676e1d267cd961cb9e5f4825beb372b7f97e` |
+| flow | `openadapt-flow` | `1.33.0` | [`v1.33.0`](https://github.com/OpenAdaptAI/openadapt-flow/tree/v1.33.0)
commit `80dc49b7296e5e6999b04124f26a647047a14b95`
tree `3074fd53f7a1673b51d610d178825a23676de644` | `openadapt_flow-1.33.0-py3-none-any.whl` `1d54ccffe3a554ecff82f69917f63f55233bd54ac1cb737058e096e4582aa494`
`openadapt_flow-1.33.0.tar.gz` `8f85bc5a9e3a8eb1c1d69178e7cfd03fc9de4d0d31832f117eacc0cc2052fd1c` |
| capture | `openadapt-capture` | `1.2.2` | [`v1.2.2`](https://github.com/OpenAdaptAI/openadapt-capture/tree/v1.2.2)
commit `06ade22948c12dcc6608bd54b5cca5c9c306e77c`
tree `b0a3b5b53f23536e01314f36aa46fd5b2d8baba6` | `openadapt_capture-1.2.2-py3-none-any.whl` `550fffe50990fa8431d332bdd5fe4755976d83baa7ad62553f50ad9e4ddcd1ae`
`openadapt_capture-1.2.2.tar.gz` `6f4298d3daadf9cced8994207e34b3116a79209ef792e98f778a0770e2f3406c` |
| privacy | `openadapt-privacy` | `1.0.3` | [`v1.0.3`](https://github.com/OpenAdaptAI/openadapt-privacy/tree/v1.0.3)
commit `43228e2b8d2e308083a9266f4bb6b247b5abdd93`
tree `d3ed6ebefca797cf36d83292be97de407bd9b1d8` | `openadapt_privacy-1.0.3-py3-none-any.whl` `ca0a92bce80be441240b3382812b001c99326a3ae3665e5d3026dee588ee3e07`
`openadapt_privacy-1.0.3.tar.gz` `2e0f201c206c67f936dd8c53a1ddfeb0effc6ca14175d97e0413be0a0d16668b` |
| types | `openadapt-types` | `0.10.1` | [`v0.10.1`](https://github.com/OpenAdaptAI/openadapt-types/tree/v0.10.1)
commit `9e0336ee92a807912338db570855a98d15919725`
tree `b63af56d5e639af1cfa7f1d008883c955e1b6ddf` | `openadapt_types-0.10.1-py3-none-any.whl` `c90a5a03721bf686895ae7212c88f178b96294d431edd37aebe9e5617fccc477`
`openadapt_types-0.10.1.tar.gz` `e39f850587ce05481c39bee87ecd266df1ddfd335cabdca23c4e2adc1df1c590` |
@@ -24,10 +24,10 @@
| Unit | Version | Selected or locked OpenAdapt packages |
|---|---:|---|
-| launcher_environment | `1.14.0` | `openadapt==1.14.0`
`openadapt-flow==1.32.0` |
-| customer_runner | `1.32.0` | `openadapt-flow==1.32.0`
`openadapt-types==0.10.1` |
+| launcher_environment | `1.14.0` | `openadapt==1.14.0`
`openadapt-flow==1.33.0` |
+| customer_runner | `1.33.0` | `openadapt-flow==1.33.0`
`openadapt-types==0.10.1` |
| desktop_sidecar | `0.15.0` | `openadapt-capture==1.2.1`
`openadapt-flow==1.27.1`
`openadapt-privacy==1.0.0`
`openadapt-types==0.7.0` |
-| agent_bridge | `2.0.1` | `openadapt-agent==2.0.1`
`openadapt-flow==1.32.0` |
+| agent_bridge | `2.0.1` | `openadapt-agent==2.0.1`
`openadapt-flow==1.33.0` |
## Selected-platform dependency compatibility
@@ -39,27 +39,27 @@ These edges show whether each selected integration version satisfies its publish
| desktop-sidecar-lock | `openadapt-desktop==0.15.0` | `openadapt-flow` | `==1.27.1` | `1.27.1` | `extra == "build"` |
| desktop-sidecar-lock | `openadapt-desktop==0.15.0` | `openadapt-privacy` | `>=1.0.0` | `1.0.0` | `always` |
| desktop-sidecar-lock | `openadapt-desktop==0.15.0` | `openadapt-types` | `==0.7.0` | `0.7.0` | `always` |
-| selected-platform | `openadapt-agent==2.0.1` | `openadapt-flow` | `<2,>=1.18.1` | `1.32.0` | `always` |
+| selected-platform | `openadapt-agent==2.0.1` | `openadapt-flow` | `<2,>=1.18.1` | `1.33.0` | `always` |
| selected-platform | `openadapt-capture==1.2.2` | `openadapt-privacy` | `>=0.1.0` | `1.0.3` | `extra == "all"`
`extra == "privacy"` |
-| selected-platform | `openadapt-flow==1.32.0` | `openadapt-capture` | `>=1.2.0` | `1.2.2` | `extra == "capture"` |
-| selected-platform | `openadapt-flow==1.32.0` | `openadapt-privacy` | `>=1.0.0` | `1.0.3` | `extra == "privacy"` |
-| selected-platform | `openadapt-flow==1.32.0` | `openadapt-types` | `<0.11.0,>=0.10.0` | `0.10.1` | `extra == "console"`
`extra == "dev"`
`extra == "interop"` |
+| selected-platform | `openadapt-flow==1.33.0` | `openadapt-capture` | `>=1.2.0` | `1.2.2` | `extra == "capture"` |
+| selected-platform | `openadapt-flow==1.33.0` | `openadapt-privacy` | `>=1.0.0` | `1.0.3` | `extra == "privacy"` |
+| selected-platform | `openadapt-flow==1.33.0` | `openadapt-types` | `<0.11.0,>=0.10.0` | `0.10.1` | `extra == "console"`
`extra == "dev"`
`extra == "interop"` |
| selected-platform | `openadapt==1.14.0` | `openadapt-capture` | `<2.0.0,>=1.2.0` | `1.2.2` | `extra == "all"`
`extra == "capture"`
`extra == "core"` |
-| selected-platform | `openadapt==1.14.0` | `openadapt-flow` | `<2.0.0,>=1.29.0` | `1.32.0` | `always`
`extra == "all"`
`extra == "browser"`
`extra == "capture"`
`extra == "core"`
`extra == "flow"`
`extra == "privacy"`
`extra == "rdp"`
`extra == "windows"`
`sys_platform == "darwin" and extra == "all"`
`sys_platform == "darwin" and extra == "macos"`
`sys_platform == "linux" and extra == "all"`
`sys_platform == "linux" and extra == "linux"` |
+| selected-platform | `openadapt==1.14.0` | `openadapt-flow` | `<2.0.0,>=1.29.0` | `1.33.0` | `always`
`extra == "all"`
`extra == "browser"`
`extra == "capture"`
`extra == "core"`
`extra == "flow"`
`extra == "privacy"`
`extra == "rdp"`
`extra == "windows"`
`sys_platform == "darwin" and extra == "all"`
`sys_platform == "darwin" and extra == "macos"`
`sys_platform == "linux" and extra == "all"`
`sys_platform == "linux" and extra == "linux"` |
## Cross-component schemas
| Contract | Owner | Accepted versions | Exact source |
|---|---|---|---|
-| `workflow_bundle` | `flow` | `schema_version` [1, 2] | [`openadapt_flow/bundle_validation.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/bundle_validation.py) `fe1e5ec441183adf1aa2209f1669f779043fb4ad1f41a651ca0f96123778240f`
[`openadapt_flow/ir.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/ir.py) `e01b5bc70341e423782765241716890840d2874139fd17a4ca9e70d6d9930739` |
+| `workflow_bundle` | `flow` | `schema_version` [1, 2] | [`openadapt_flow/bundle_validation.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/bundle_validation.py) `fe1e5ec441183adf1aa2209f1669f779043fb4ad1f41a651ca0f96123778240f`
[`openadapt_flow/ir.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/ir.py) `e01b5bc70341e423782765241716890840d2874139fd17a4ca9e70d6d9930739` |
| `capture_structural_observation` | `capture` | `openadapt.capture.structural-observation/v` [1] | [`openadapt_capture/structural.py`](https://github.com/OpenAdaptAI/openadapt-capture/blob/06ade22948c12dcc6608bd54b5cca5c9c306e77c/openadapt_capture/structural.py) `8f8bce37148a3357ace147c46a7c45e6d5501b70622b24b1ac2490f2def304fc` |
| `control_overlay_frame` | `types` | `openadapt.control-overlay-frame/v` [1, 2] | [`openadapt_types/control_overlay.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/control_overlay.py) `3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790`
[`openadapt_types/control_overlay_tracking.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/control_overlay_tracking.py) `af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755` |
| `control_overlay_timeline` | `types` | `openadapt.control-overlay-timeline/v` [1, 2] | [`openadapt_types/control_overlay.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/control_overlay.py) `3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790`
[`openadapt_types/control_overlay_tracking.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/control_overlay_tracking.py) `af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755` |
| `human_decision_task` | `types` | `openadapt.human-decision-task/v` [1, 2] | [`openadapt_types/human_decision.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/human_decision.py) `6ed5d2db82f5c73dfab568868f13f7a2cbfde6fb7b3f05b027b40c503ab04e29` |
| `human_decision_receipt` | `types` | `openadapt.human-decision-receipt/v` [1] | [`openadapt_types/human_decision.py`](https://github.com/OpenAdaptAI/openadapt-types/blob/9e0336ee92a807912338db570855a98d15919725/openadapt_types/human_decision.py) `6ed5d2db82f5c73dfab568868f13f7a2cbfde6fb7b3f05b027b40c503ab04e29` |
-| `human_decision_relay` | `flow` | `openadapt.human-decision-relay/v` [2] | [`openadapt_flow/console/decision_relay.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/console/decision_relay.py) `d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292` |
-| `remote_decision_projection` | `flow` | `openadapt.remote-decision-projection/v` [1] | [`openadapt_flow/console/human_decisions.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/console/human_decisions.py) `02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477` |
-| `runtime_validation` | `flow` | `openadapt.runtime-validation/v` [1, 2, 3] | [`openadapt_flow/runtime_validation.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/runtime_validation.py) `69a27484f625e78b826291adba517cc00ec6c9a89477d09c703af90cc6d6b73e` |
+| `human_decision_relay` | `flow` | `openadapt.human-decision-relay/v` [2] | [`openadapt_flow/console/decision_relay.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/console/decision_relay.py) `d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292` |
+| `remote_decision_projection` | `flow` | `openadapt.remote-decision-projection/v` [1] | [`openadapt_flow/console/human_decisions.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/console/human_decisions.py) `02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477` |
+| `runtime_validation` | `flow` | `openadapt.runtime-validation/v` [1, 2, 3] | [`openadapt_flow/runtime_validation.py`](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/runtime_validation.py) `69a27484f625e78b826291adba517cc00ec6c9a89477d09c703af90cc6d6b73e` |
## Host operating systems
@@ -80,5 +80,5 @@ These edges show whether each selected integration version satisfies its publish
## Qualification evidence
- [openadapt-public-status](https://openadapt.ai/status.json): Canonical machine-readable release, capability, and substrate qualification status, maintained in openadapt-web (public/status.json).
-- [flow-public-demo-evidence-packs](https://github.com/OpenAdaptAI/openadapt-flow/tree/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/public-demo/evidence-packs): Versioned public evidence packs with per-pack manifest files, replay evidence, and fault-case results.
-- [flow-effectbench-task-pack](https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/benchmark/effectbench/task_pack/manifest.json): Effect-verification benchmark task pack manifest used by the flow qualification harness.
+- [flow-public-demo-evidence-packs](https://github.com/OpenAdaptAI/openadapt-flow/tree/80dc49b7296e5e6999b04124f26a647047a14b95/public-demo/evidence-packs): Versioned public evidence packs with per-pack manifest files, replay evidence, and fault-case results.
+- [flow-effectbench-task-pack](https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/benchmark/effectbench/task_pack/manifest.json): Effect-verification benchmark task pack manifest used by the flow qualification harness.
diff --git a/openadapt/cli.py b/openadapt/cli.py
index e3550277e..25aa746be 100644
--- a/openadapt/cli.py
+++ b/openadapt/cli.py
@@ -61,7 +61,7 @@ def main():
\b
Quick Start:
- python -m pip install --upgrade 'openadapt[browser]'
+ python -m pip install --upgrade openadapt
openadapt quickstart
\b
@@ -112,7 +112,7 @@ def _run_flow(argv: list[str]) -> None:
_PYTHON_REMEDY = (
"OpenAdapt needs Python 3.10\u20133.12. Easiest fix: "
"curl -LsSf https://astral.sh/uv/install.sh | sh && "
- "uv venv --python 3.12 && uv pip install 'openadapt[browser]'\n"
+ "uv venv --python 3.12 && uv pip install openadapt\n"
"Or use the installer script: https://raw.githubusercontent.com/"
"OpenAdaptAI/openadapt-flow/main/scripts/install.sh"
)
@@ -366,8 +366,8 @@ def deploy(backend: str, secret_ref: tuple[str, ...]) -> None:
else:
failures.append("browser")
click.echo(
- " [SETUP] install the web extra before recording or replay: "
- "python -m pip install 'openadapt[browser]'"
+ " [MISSING] the base OpenAdapt install does not contain "
+ "Playwright. Run: python -m pip install --upgrade openadapt"
)
elif backend == "rdp":
if find_spec("aardwolf") is not None:
@@ -1034,11 +1034,9 @@ def doctor(backend: str | None):
else:
playwright = find_spec("playwright") is not None
if not playwright:
- prefix = "[SETUP]" if backend == "web" else "[--]"
click.echo(
- f" {prefix} Browser: optional and not installed. Run "
- "`python -m pip install 'openadapt[browser]'` before a web "
- "recording or replay."
+ " [MISSING] Browser: the base install does not contain "
+ "Playwright. Run `python -m pip install --upgrade openadapt`."
)
else:
try:
@@ -1060,6 +1058,7 @@ def doctor(backend: str | None):
click.echo("\nCore packages (installed with `pip install openadapt`):")
core = [
"openadapt_flow",
+ "playwright",
]
for pkg in core:
# find_spec checks installability without executing package code
@@ -1078,7 +1077,6 @@ def doctor(backend: str | None):
# install it rather than flagging it. Maps import name -> extra name.
click.echo("\nOptional packages (install with `pip install openadapt[...]`):")
optional = [
- ("playwright", "browser"),
("openadapt_capture", "capture"),
("openadapt_ml", "ml"),
("openadapt_evals", "evals"),
diff --git a/platform-manifest.json b/platform-manifest.json
index bea9ca957..16f633070 100644
--- a/platform-manifest.json
+++ b/platform-manifest.json
@@ -1,7 +1,7 @@
{
"manifest_kind": "openadapt-platform-release-manifest",
"schema_version": "1.3.0",
- "generated_at": "2026-08-22T22:03:24+00:00",
+ "generated_at": "2026-08-26T14:19:29+00:00",
"generation": {
"files": [
{
@@ -278,7 +278,7 @@
},
"flow": {
"package": "openadapt-flow",
- "version": "1.32.0",
+ "version": "1.33.0",
"source": "pypi",
"requires_python": "<3.13,>=3.10",
"requires": {
@@ -335,23 +335,23 @@
],
"provenance": {
"repository": "OpenAdaptAI/openadapt-flow",
- "release_ref": "v1.32.0",
- "commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
- "tree": "191b54985409034933b57e10fd08a17739277a47",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/tree/v1.32.0"
+ "release_ref": "v1.33.0",
+ "commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
+ "tree": "3074fd53f7a1673b51d610d178825a23676de644",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/tree/v1.33.0"
},
"artifacts": [
{
"type": "bdist_wheel",
- "filename": "openadapt_flow-1.32.0-py3-none-any.whl",
- "url": "https://files.pythonhosted.org/packages/a9/88/eb6f1c789298c1dd0ff92050cd6bf0ef562eff328e97c1c13e5e1b1a8e03/openadapt_flow-1.32.0-py3-none-any.whl",
- "sha256": "d58dcf8b7e54c8a45199db4390a588dc261bb754c5ab2af0fdb540e44cb6bb8a"
+ "filename": "openadapt_flow-1.33.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/99/b5/2e57d3f6c2147b3528114c8f20cc89c64ec6184fcce2b556e4e18fc75f75/openadapt_flow-1.33.0-py3-none-any.whl",
+ "sha256": "1d54ccffe3a554ecff82f69917f63f55233bd54ac1cb737058e096e4582aa494"
},
{
"type": "sdist",
- "filename": "openadapt_flow-1.32.0.tar.gz",
- "url": "https://files.pythonhosted.org/packages/df/25/f8adeb01a20a7034d1f6dc24d7da4ca04c23d7182fd39c8eeafbfe6a3153/openadapt_flow-1.32.0.tar.gz",
- "sha256": "c3125f16c1b12420dff4a3af4c3d676e1d267cd961cb9e5f4825beb372b7f97e"
+ "filename": "openadapt_flow-1.33.0.tar.gz",
+ "url": "https://files.pythonhosted.org/packages/2c/b5/478a1bad39e4ed2f12f02625842aa7f1bdbcb5f5244d1e0fada2791994be/openadapt_flow-1.33.0.tar.gz",
+ "sha256": "8f85bc5a9e3a8eb1c1d69178e7cfd03fc9de4d0d31832f117eacc0cc2052fd1c"
}
]
},
@@ -579,20 +579,20 @@
},
"selected": {
"openadapt": "1.14.0",
- "openadapt-flow": "1.32.0"
+ "openadapt-flow": "1.33.0"
}
},
"customer_runner": {
"kind": "customer-controlled-runner",
- "version": "1.32.0",
+ "version": "1.33.0",
"source_component": "flow",
"entry_point": "openadapt-flow",
"requirements": {
- "openadapt-flow": "==1.32.0",
+ "openadapt-flow": "==1.33.0",
"openadapt-types": "<0.11.0,>=0.10.0"
},
"selected": {
- "openadapt-flow": "1.32.0",
+ "openadapt-flow": "1.33.0",
"openadapt-types": "0.10.1"
}
},
@@ -628,7 +628,7 @@
},
"selected": {
"openadapt-agent": "2.0.1",
- "openadapt-flow": "1.32.0"
+ "openadapt-flow": "1.33.0"
}
}
},
@@ -705,7 +705,7 @@
"target_role": "flow",
"target_package": "openadapt-flow",
"requires": "<2,>=1.18.1",
- "resolved": "1.32.0",
+ "resolved": "1.33.0",
"activations": [
{
"extras": null,
@@ -737,7 +737,7 @@
"scope": "selected-platform",
"source_role": "flow",
"source_package": "openadapt-flow",
- "source_version": "1.32.0",
+ "source_version": "1.33.0",
"target_role": "capture",
"target_package": "openadapt-capture",
"requires": ">=1.2.0",
@@ -753,7 +753,7 @@
"scope": "selected-platform",
"source_role": "flow",
"source_package": "openadapt-flow",
- "source_version": "1.32.0",
+ "source_version": "1.33.0",
"target_role": "privacy",
"target_package": "openadapt-privacy",
"requires": ">=1.0.0",
@@ -769,7 +769,7 @@
"scope": "selected-platform",
"source_role": "flow",
"source_package": "openadapt-flow",
- "source_version": "1.32.0",
+ "source_version": "1.33.0",
"target_role": "types",
"target_package": "openadapt-types",
"requires": "<0.11.0,>=0.10.0",
@@ -821,7 +821,7 @@
"target_role": "flow",
"target_package": "openadapt-flow",
"requires": "<2.0.0,>=1.29.0",
- "resolved": "1.32.0",
+ "resolved": "1.33.0",
"activations": [
{
"extras": null,
@@ -909,17 +909,17 @@
],
"minimum": 1,
"maximum": 2,
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_files": [
{
"path": "openadapt_flow/bundle_validation.py",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/bundle_validation.py",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/bundle_validation.py",
"git_blob": "2202f276d9ceb2578d58a77a864d2075fd49435c",
"sha256": "fe1e5ec441183adf1aa2209f1669f779043fb4ad1f41a651ca0f96123778240f"
},
{
"path": "openadapt_flow/ir.py",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/ir.py",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/ir.py",
"git_blob": "b54bf8d60e5709de2e6fb7cee2388bb5a7035abb",
"sha256": "e01b5bc70341e423782765241716890840d2874139fd17a4ca9e70d6d9930739"
}
@@ -1038,11 +1038,11 @@
],
"minimum": 2,
"maximum": 2,
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_files": [
{
"path": "openadapt_flow/console/decision_relay.py",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/console/decision_relay.py",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/console/decision_relay.py",
"git_blob": "297d2f71727f83496221091a4237d704c25665d6",
"sha256": "d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292"
}
@@ -1056,11 +1056,11 @@
],
"minimum": 1,
"maximum": 1,
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_files": [
{
"path": "openadapt_flow/console/human_decisions.py",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/console/human_decisions.py",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/console/human_decisions.py",
"git_blob": "caaf87396aca4770eace5eead3fdf6515e31fbfc",
"sha256": "02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477"
}
@@ -1076,11 +1076,11 @@
],
"minimum": 1,
"maximum": 3,
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_files": [
{
"path": "openadapt_flow/runtime_validation.py",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/openadapt_flow/runtime_validation.py",
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/openadapt_flow/runtime_validation.py",
"git_blob": "5c737d17aa9eaa3496ba01b61c2e33ce400c1492",
"sha256": "69a27484f625e78b826291adba517cc00ec6c9a89477d09c703af90cc6d6b73e"
}
@@ -1174,10 +1174,10 @@
"repository": "OpenAdaptAI/openadapt-flow",
"path": "public-demo/evidence-packs",
"description": "Versioned public evidence packs with per-pack manifest files, replay evidence, and fault-case results.",
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_object_type": "tree",
"source_object_sha": "2eac2252f62349e873b461866546dd0295169a19",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/tree/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/public-demo/evidence-packs"
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/tree/80dc49b7296e5e6999b04124f26a647047a14b95/public-demo/evidence-packs"
},
{
"id": "flow-effectbench-task-pack",
@@ -1186,10 +1186,10 @@
"repository": "OpenAdaptAI/openadapt-flow",
"path": "benchmark/effectbench/task_pack/manifest.json",
"description": "Effect-verification benchmark task pack manifest used by the flow qualification harness.",
- "source_commit": "d1b054c718d60465fb8a2e1853e6a84c7f26dec2",
+ "source_commit": "80dc49b7296e5e6999b04124f26a647047a14b95",
"source_object_type": "blob",
"source_object_sha": "1c568d2289342e10e3556c5c46cd08a0e370ac84",
- "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/d1b054c718d60465fb8a2e1853e6a84c7f26dec2/benchmark/effectbench/task_pack/manifest.json"
+ "url": "https://github.com/OpenAdaptAI/openadapt-flow/blob/80dc49b7296e5e6999b04124f26a647047a14b95/benchmark/effectbench/task_pack/manifest.json"
}
],
"signature": {
diff --git a/pyproject.toml b/pyproject.toml
index 7a2982ba3..bcd6c4f9c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -28,22 +28,22 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
-# Base install: the CLI plus the flagship demonstration compiler, so
-# `pip install openadapt` yields a working `openadapt flow` out of the box.
-# All other capabilities (capture, ml, evals, ...) remain opt-in extras.
+# Base install: the CLI, the flagship demonstration compiler, and the browser
+# driver used by the bundled tutorial. `pip install openadapt` must make the
+# public `openadapt quickstart` command work without a second package install.
+# Playwright downloads Chromium lazily on the first browser action. All other
+# capabilities (capture, ml, evals, ...) remain opt-in extras.
dependencies = [
"click>=8.0.0",
- "openadapt-flow[hosted]>=1.29.0,<2.0.0",
+ "openadapt-flow[browser,hosted]>=1.29.0,<2.0.0",
]
[project.optional-dependencies]
# Individual packages
browser = [
- # Web recording/replay only. The base launcher stays lightweight for
- # native desktop, RDP, and Citrix users. Select Flow's browser contract
- # instead of duplicating its current driver dependency here, so future
- # browser-runtime changes remain compatible across the package boundary.
- # Chromium remains lazy on first use.
+ # Kept as a compatibility alias for existing install commands. The base
+ # launcher now selects this Flow contract because the bundled quickstart
+ # uses the browser. Chromium remains lazy on first use.
"openadapt-flow[browser]>=1.29.0,<2.0.0",
]
# Local human desktop recording. Flow owns the supported capture adapter
diff --git a/scripts/quickstart_lifecycle.py b/scripts/quickstart_lifecycle.py
index e0ad88c36..9af1726df 100644
--- a/scripts/quickstart_lifecycle.py
+++ b/scripts/quickstart_lifecycle.py
@@ -189,7 +189,7 @@ def run_lifecycle(
"-m",
"pip",
"install",
- f"{launcher_wheel}[browser]",
+ str(launcher_wheel),
],
cwd=artifacts,
env=env,
diff --git a/tests/test_cli_quickstart_polish.py b/tests/test_cli_quickstart_polish.py
index 697d6fe68..e30a16edf 100644
--- a/tests/test_cli_quickstart_polish.py
+++ b/tests/test_cli_quickstart_polish.py
@@ -97,7 +97,7 @@ def raise_externally_managed(_argv):
assert result.exit_code != 0
assert "OpenAdapt needs Python 3.10\u20133.12" in result.output
- assert "uv pip install 'openadapt[browser]'" in result.output
+ assert "uv pip install openadapt" in result.output
@pytest.mark.parametrize(
diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py
index aec814efa..1260b7bba 100644
--- a/tests/test_cli_smoke.py
+++ b/tests/test_cli_smoke.py
@@ -222,10 +222,11 @@ def test_distribution_metadata_matches_engine_python_range():
assert {term.strip() for term in actual.split(",")} == {">=3.10", "<3.13"}
-def test_doctor_lists_flow_as_core_not_extras():
- """`openadapt doctor` must treat openadapt-flow as core and the opt-in
- extras (capture/ml/evals/viewer/...) as optional, never flagging a
- missing extra as a failure."""
+def test_doctor_lists_quickstart_dependencies_as_core_not_extras():
+ """`openadapt doctor` must treat Flow and Playwright as base dependencies.
+
+ The other capabilities stay optional and must not cause a failure.
+ """
runner = CliRunner()
result = runner.invoke(cli_main, ["doctor"])
assert result.exit_code == 0, result.output
@@ -238,8 +239,10 @@ def test_doctor_lists_flow_as_core_not_extras():
core_section = out[core_idx:optional_idx]
optional_section = out[optional_idx:]
- # flow is core.
+ # Flow and the browser tutorial driver are core.
assert "openadapt_flow" in core_section
+ assert "playwright" in core_section
+ assert "playwright" not in optional_section
# The excluded-by-default extras must appear only in the optional
# section and must not be reported as [MISSING].
for extra_pkg in (
@@ -263,7 +266,10 @@ def test_launcher_flow_and_substrate_extras_metadata():
)["project"]
extras = metadata["optional-dependencies"]
- assert metadata["dependencies"].count("openadapt-flow[hosted]>=1.29.0,<2.0.0") == 1
+ assert (
+ metadata["dependencies"].count("openadapt-flow[browser,hosted]>=1.29.0,<2.0.0")
+ == 1
+ )
assert extras["flow"] == ["openadapt-flow>=1.29.0,<2.0.0"]
assert extras["browser"] == ["openadapt-flow[browser]>=1.29.0,<2.0.0"]
assert extras["privacy"] == ["openadapt-flow[privacy]>=1.29.0,<2.0.0"]
@@ -414,7 +420,10 @@ def test_deploy_preflight_fails_without_web_runtime(monkeypatch):
result = CliRunner().invoke(cli_main, ["deploy", "--backend", "web"])
assert result.exit_code != 0
- assert "[SETUP] install the web extra" in result.output
+ assert (
+ "[MISSING] the base OpenAdapt install does not contain Playwright"
+ in result.output
+ )
assert "Preflight failed" in result.output
assert "Preflight passed" not in result.output
diff --git a/tests/test_release_artifacts.py b/tests/test_release_artifacts.py
index 48e11f80a..4f0f00b9e 100644
--- a/tests/test_release_artifacts.py
+++ b/tests/test_release_artifacts.py
@@ -197,7 +197,7 @@ def test_all_artifact_metadata_selects_platform_substrate_dependencies(
assert {"all", "capture", "windows", "macos", "linux", "rdp"} <= provided_extras
flow_extras = _flow_extras_selected_by_launcher_all(sys_platform)
- assert {"hosted", "capture", "privacy", "windows", "rdp"} <= flow_extras
+ assert {"browser", "hosted", "capture", "privacy", "windows", "rdp"} <= flow_extras
if platform_extra is not None:
assert platform_extra in flow_extras
assert flow_extras.isdisjoint(excluded_extra)
diff --git a/uv.lock b/uv.lock
index ab94fb1a8..cae7e3948 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2319,7 +2319,7 @@ version = "1.14.0"
source = { editable = "." }
dependencies = [
{ name = "click" },
- { name = "openadapt-flow", extra = ["hosted"] },
+ { name = "openadapt-flow", extra = ["browser", "hosted"] },
]
[package.optional-dependencies]
@@ -2400,7 +2400,7 @@ requires-dist = [
{ name = "openadapt-flow", marker = "extra == 'flow'", specifier = ">=1.29.0,<2.0.0" },
{ name = "openadapt-flow", extras = ["browser"], marker = "extra == 'browser'", specifier = ">=1.29.0,<2.0.0" },
{ name = "openadapt-flow", extras = ["capture"], marker = "extra == 'capture'", specifier = ">=1.29.0,<2.0.0" },
- { name = "openadapt-flow", extras = ["hosted"], specifier = ">=1.29.0,<2.0.0" },
+ { name = "openadapt-flow", extras = ["browser", "hosted"], specifier = ">=1.29.0,<2.0.0" },
{ name = "openadapt-flow", extras = ["linux"], marker = "sys_platform == 'linux' and extra == 'linux'", specifier = ">=1.29.0,<2.0.0" },
{ name = "openadapt-flow", extras = ["macos"], marker = "sys_platform == 'darwin' and extra == 'macos'", specifier = ">=1.29.0,<2.0.0" },
{ name = "openadapt-flow", extras = ["privacy"], marker = "extra == 'privacy'", specifier = ">=1.29.0,<2.0.0" },