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" },