From 79fc3a64fa8efabaebc05350fa81d3e29f08e9fb Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 2 Nov 2026 19:24:25 -0500 Subject: [PATCH] chore(release): openadapt 1.19.0 on openadapt-flow 2.5.0 Bumps the launcher to 1.19.0 and requires openadapt-flow>=2.5.0,<3.0.0 in every dependency and extra, and in doctor and deploy: `openadapt shadow` forwards to Flow's shadow command, and `openadapt verify serve` offers its recheck, neither in Flow 2.4 or earlier. The quickstart's own minimum (2.2) is unchanged. Changelog for 1.19.0 (shadow, verify, bench medplum, setup), the root uv.lock relocked (openadapt 1.19.0, openadapt-flow 2.5.0), and platform-manifest.json regenerated with flow pinned to the published 2.5.0 (openadapt-flow-v2.5.0); the other selections are unchanged. --- CHANGELOG.md | 30 +++++++++ docs/platform-compatibility-report.md | 32 ++++----- llms-full.txt | 2 + openadapt/cli.py | 8 +-- platform-manifest.json | 82 ++++++++++++------------ pyproject.toml | 26 ++++---- tests/test_cli_shell_hints.py | 4 +- tests/test_cli_smoke.py | 40 ++++++------ tests/test_deploy_preflight_readiness.py | 2 +- tests/test_flow_floor.py | 8 +-- uv.lock | 26 ++++---- 11 files changed, 146 insertions(+), 114 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 551d8dcac9..114bbdeb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ +## v1.19.0 (2026-11-02) + +### Breaking Changes + +- Require openadapt-flow 2.5 (`>=2.5.0,<3.0.0`). `openadapt shadow` forwards + to Flow's shadow command, and `openadapt verify serve` offers its recheck; + neither is in Flow 2.4 or earlier. `openadapt doctor` and `openadapt deploy` + report an older Flow as unsupported. + +### Features + +- `openadapt shadow` runs beside an agent you already have, as a loopback + pass-through proxy. It checks each write the agent makes against the + system of record, checks each confirmed write again later, and writes + `report.html` and `report.json`. It never blocks, changes or resends a write + ([#1678](https://github.com/OpenAdaptAI/OpenAdapt/pull/1678)). +- `openadapt verify` checks any agent's writes against a contract you own + and returns `CONFIRMED`, `REFUTED` or `UNCERTAIN`. `openadapt verify serve` + offers the same check to any MCP client, recheck included, and `openadapt + verify ledger` lists, reconciles and releases writes whose outcome isn't + known yet ([#1589](https://github.com/OpenAdaptAI/OpenAdapt/pull/1589), + [#1628](https://github.com/OpenAdaptAI/OpenAdapt/pull/1628), + [#1669](https://github.com/OpenAdaptAI/OpenAdapt/pull/1669)). +- `openadapt bench medplum` runs the public Medplum write benchmark with your + own agent ([#1652](https://github.com/OpenAdaptAI/OpenAdapt/pull/1652)). +- `openadapt setup` adds the OpenAdapt MCP server and a skill to Claude Code, + Cursor, Codex and Gemini CLI, so the agent can turn a read-only browser + task into a tool it calls again. It prints every change, and `--dry-run` + and `--undo` are there. + ## v1.18.0 (2026-10-20) ### Breaking Changes diff --git a/docs/platform-compatibility-report.md b/docs/platform-compatibility-report.md index 294e817095..2c1b4199d6 100644 --- a/docs/platform-compatibility-report.md +++ b/docs/platform-compatibility-report.md @@ -2,7 +2,7 @@ -- Generated: `2026-10-20T17:25:50+00:00` +- Generated: `2026-11-03T00:23:35+00:00` - Selection: `explicit-published` - Compatibility: **dependency-compatible** - Signature: `unsigned (signing infrastructure pending)` @@ -12,7 +12,7 @@ | Role | Package | Version | Release source reference | Published artifacts | |---|---|---:|---|---| | launcher | `openadapt` | `1.17.0` | [`v1.17.0`](https://github.com/OpenAdaptAI/OpenAdapt/tree/v1.17.0)
commit `e022d97ee8b3c3992f4a4cb6e522f1532fef0834`
tree `2e0efeaa337a26d3425320ffa8f9aa3ac31d3f9c` | `openadapt-1.17.0-py3-none-any.whl` `c33c069c8cd9c270562200339b631fb77423b5b7f24364b5f0a6a0730e5ca8b8`
`openadapt-1.17.0.tar.gz` `03926f94f4d9d37eeb8c6c9cbdc94516d43c0ace971f2282b3310d77d73b6547` | -| flow | `openadapt-flow` | `2.3.0` | [`openadapt-flow-v2.3.0`](https://github.com/OpenAdaptAI/OpenAdapt/tree/openadapt-flow-v2.3.0/packages/flow)
commit `b6a9d46b00b92454c18e844f0a8f6929330e87b6`
tree `14bf88ccefe00708bb51003d6262876c555e7271` | `openadapt_flow-2.3.0-py3-none-any.whl` `6a2dbd22eb15bd449fc12a6dc36dcc8da7c0316f9faac80cbff8d6e9a433222b`
`openadapt_flow-2.3.0.tar.gz` `39f3b853987227063257a1ffcd402ca3a3120e508d901578622cd0351f1ce12d` | +| flow | `openadapt-flow` | `2.5.0` | [`openadapt-flow-v2.5.0`](https://github.com/OpenAdaptAI/OpenAdapt/tree/openadapt-flow-v2.5.0/packages/flow)
commit `5a3bf49a0bf2d662430386295a1c34036c064d58`
tree `cab536c90e79fcfe887b8876e884ec2ed651f23e` | `openadapt_flow-2.5.0-py3-none-any.whl` `1dbc5d42d103cfa8a452d95805dde60c7d460035ec4d81df5cc642a32f118339`
`openadapt_flow-2.5.0.tar.gz` `54d99e77976ee7d9e6bc171b2ea148497528ead77b226fdf6fd4713b37c689b3` | | 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.1.2` | [`v1.1.2`](https://github.com/OpenAdaptAI/openadapt-privacy/tree/v1.1.2)
commit `9ae96d8ed73ea5b9e445d0604b5db48788936a04`
tree `fe59ca5f04fc99d16424e9228dcd797b05115cb8` | `openadapt_privacy-1.1.2-py3-none-any.whl` `6e542b2fea44bdf8872430687946ec805fef22dc7d228a56a1e65871beebe47a`
`openadapt_privacy-1.1.2.tar.gz` `d90287edaa13470955f15d5f6eeb37b075678aeb55de324f8b8207682009bcc2` | | types | `openadapt-types` | `0.24.0` | [`openadapt-types-v0.24.0`](https://github.com/OpenAdaptAI/OpenAdapt/tree/openadapt-types-v0.24.0/packages/types)
commit `f2f04c5b432d88b262d46103a542b0e2c3dcc8a9`
tree `38ccf341ec74a0dd0facc9f64343c27644a7ca7d` | `openadapt_types-0.24.0-py3-none-any.whl` `8025e8a4dc9235fd81d4b24ae7fa7e544120abdb8d4ee7df160e4f50d9230d75`
`openadapt_types-0.24.0.tar.gz` `16dcd1da1c2c78c08d650a19eb9cc439474f996812a87198b316d51bfac443db` | @@ -23,10 +23,10 @@ | Unit | Version | Selected or locked OpenAdapt packages | |---|---:|---| -| launcher_environment | `1.17.0` | `openadapt==1.17.0`
`openadapt-flow==2.3.0` | -| customer_runner | `2.3.0` | `openadapt-flow==2.3.0`
`openadapt-types==0.24.0` | +| launcher_environment | `1.17.0` | `openadapt==1.17.0`
`openadapt-flow==2.5.0` | +| customer_runner | `2.5.0` | `openadapt-flow==2.5.0`
`openadapt-types==0.24.0` | | desktop_sidecar | `0.16.0` | `openadapt-capture==1.2.1`
`openadapt-flow==1.34.0`
`openadapt-privacy==1.0.0`
`openadapt-types==0.10.0` | -| agent_bridge | `2.2.1` | `openadapt-agent==2.2.1`
`openadapt-flow==2.3.0` | +| agent_bridge | `2.2.1` | `openadapt-agent==2.2.1`
`openadapt-flow==2.5.0` | ## Selected-platform dependency compatibility @@ -38,29 +38,29 @@ These edges show whether each selected integration version satisfies its publish | desktop-sidecar-lock | `openadapt-desktop==0.16.0` | `openadapt-flow` | `==1.34.0` | `1.34.0` | `extra == "build"` | | desktop-sidecar-lock | `openadapt-desktop==0.16.0` | `openadapt-privacy` | `>=1.0.0` | `1.0.0` | `always` | | desktop-sidecar-lock | `openadapt-desktop==0.16.0` | `openadapt-types` | `==0.10.0` | `0.10.0` | `always` | -| selected-platform | `openadapt-agent==2.2.1` | `openadapt-flow` | `<3,>=2.2.0` | `2.3.0` | `always`
`extra == "tutorial"` | +| selected-platform | `openadapt-agent==2.2.1` | `openadapt-flow` | `<3,>=2.2.0` | `2.5.0` | `always`
`extra == "tutorial"` | | selected-platform | `openadapt-agent==2.2.1` | `openadapt-privacy` | `>=1.1.2` | `1.1.2` | `extra == "repair-screens"` | | selected-platform | `openadapt-capture==1.2.2` | `openadapt-privacy` | `>=0.1.0` | `1.1.2` | `extra == "all"`
`extra == "privacy"` | -| selected-platform | `openadapt-flow==2.3.0` | `openadapt-capture` | `>=1.2.0` | `1.2.2` | `extra == "capture"` | -| selected-platform | `openadapt-flow==2.3.0` | `openadapt-privacy` | `>=1.0.0` | `1.1.2` | `extra == "privacy"` | -| selected-platform | `openadapt-flow==2.3.0` | `openadapt-types` | `<0.25.0,>=0.24.0` | `0.24.0` | `always` | +| selected-platform | `openadapt-flow==2.5.0` | `openadapt-capture` | `>=1.2.0` | `1.2.2` | `extra == "capture"` | +| selected-platform | `openadapt-flow==2.5.0` | `openadapt-privacy` | `>=1.0.0` | `1.1.2` | `extra == "privacy"` | +| selected-platform | `openadapt-flow==2.5.0` | `openadapt-types` | `<0.25.0,>=0.24.0` | `0.24.0` | `always` | | selected-platform | `openadapt==1.17.0` | `openadapt-agent` | `<3,>=2.1.0` | `2.2.1` | `python_version < "3.13"`
`python_version < "3.13" and extra == "agent"`
`python_version < "3.13" and extra == "all"` | | selected-platform | `openadapt==1.17.0` | `openadapt-capture` | `<2.0.0,>=1.2.0` | `1.2.2` | `extra == "all"`
`extra == "capture"`
`extra == "core"` | -| selected-platform | `openadapt==1.17.0` | `openadapt-flow` | `<3.0.0,>=2.0.0` | `2.3.0` | `(sys_platform == "darwin" and python_version < "3.13") and extra == "all"`
`(sys_platform == "darwin" and python_version < "3.13") and extra == "macos"`
`(sys_platform == "linux" and python_version < "3.13") and extra == "all"`
`(sys_platform == "linux" and python_version < "3.13") and extra == "linux"`
`python_version < "3.13"`
`python_version < "3.13" and extra == "all"`
`python_version < "3.13" and extra == "browser"`
`python_version < "3.13" and extra == "capture"`
`python_version < "3.13" and extra == "core"`
`python_version < "3.13" and extra == "flow"`
`python_version < "3.13" and extra == "privacy"`
`python_version < "3.13" and extra == "rdp"`
`python_version < "3.13" and extra == "windows"` | +| selected-platform | `openadapt==1.17.0` | `openadapt-flow` | `<3.0.0,>=2.0.0` | `2.5.0` | `(sys_platform == "darwin" and python_version < "3.13") and extra == "all"`
`(sys_platform == "darwin" and python_version < "3.13") and extra == "macos"`
`(sys_platform == "linux" and python_version < "3.13") and extra == "all"`
`(sys_platform == "linux" and python_version < "3.13") and extra == "linux"`
`python_version < "3.13"`
`python_version < "3.13" and extra == "all"`
`python_version < "3.13" and extra == "browser"`
`python_version < "3.13" and extra == "capture"`
`python_version < "3.13" and extra == "core"`
`python_version < "3.13" and extra == "flow"`
`python_version < "3.13" and extra == "privacy"`
`python_version < "3.13" and extra == "rdp"`
`python_version < "3.13" and extra == "windows"` | ## Cross-component schemas | Contract | Owner | Accepted versions | Exact source | |---|---|---|---| -| `workflow_bundle` | `flow` | `schema_version` [1, 2] | [`packages/flow/openadapt_flow/bundle_validation.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/bundle_validation.py) `936c42daa7618a07222a6807080045aa5e8a25ebcf4dd2c7488351fc13663d18`
[`packages/flow/openadapt_flow/ir.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/ir.py) `739fe7f4841a018668840559cead446d25c6a22d1a33ed3721bd553d10e9366a` | +| `workflow_bundle` | `flow` | `schema_version` [1, 2] | [`packages/flow/openadapt_flow/bundle_validation.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/bundle_validation.py) `63532fb8e49f25a8aba8dccca505362a9293b8db9cbc0f2904dd8f9a6e23fea8`
[`packages/flow/openadapt_flow/ir.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/ir.py) `efb7fdce6fa625f631901389ca767b016f4db3111caa2905321ff3da675e376d` | | `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] | [`packages/types/openadapt_types/control_overlay.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/control_overlay.py) `3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790`
[`packages/types/openadapt_types/control_overlay_tracking.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/control_overlay_tracking.py) `af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755` | | `control_overlay_timeline` | `types` | `openadapt.control-overlay-timeline/v` [1, 2] | [`packages/types/openadapt_types/control_overlay.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/control_overlay.py) `3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790`
[`packages/types/openadapt_types/control_overlay_tracking.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/control_overlay_tracking.py) `af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755` | | `human_decision_task` | `types` | `openadapt.human-decision-task/v` [1, 2] | [`packages/types/openadapt_types/human_decision.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/human_decision.py) `0bb39a3575f511e10d01d92858b340982adee2f0fc20d2409441dbc0b2c55c4f` | | `human_decision_receipt` | `types` | `openadapt.human-decision-receipt/v` [1] | [`packages/types/openadapt_types/human_decision.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/f2f04c5b432d88b262d46103a542b0e2c3dcc8a9/packages/types/openadapt_types/human_decision.py) `0bb39a3575f511e10d01d92858b340982adee2f0fc20d2409441dbc0b2c55c4f` | -| `human_decision_relay` | `flow` | `openadapt.human-decision-relay/v` [2] | [`packages/flow/openadapt_flow/console/decision_relay.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/console/decision_relay.py) `d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292` | -| `remote_decision_projection` | `flow` | `openadapt.remote-decision-projection/v` [1] | [`packages/flow/openadapt_flow/console/human_decisions.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/console/human_decisions.py) `02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477` | -| `runtime_validation` | `flow` | `openadapt.runtime-validation/v` [1, 2, 3] | [`packages/flow/openadapt_flow/runtime_validation.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/runtime_validation.py) `a5a220f570c5ee5769ac2f21d8d140bb69373d4de2ccc0ebfd08540122883f0e` | +| `human_decision_relay` | `flow` | `openadapt.human-decision-relay/v` [2] | [`packages/flow/openadapt_flow/console/decision_relay.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/console/decision_relay.py) `d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292` | +| `remote_decision_projection` | `flow` | `openadapt.remote-decision-projection/v` [1] | [`packages/flow/openadapt_flow/console/human_decisions.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/console/human_decisions.py) `02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477` | +| `runtime_validation` | `flow` | `openadapt.runtime-validation/v` [1, 2, 3] | [`packages/flow/openadapt_flow/runtime_validation.py`](https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/runtime_validation.py) `a5a220f570c5ee5769ac2f21d8d140bb69373d4de2ccc0ebfd08540122883f0e` | ## Host operating systems @@ -82,5 +82,5 @@ Compatibility and delivery facts do not assign lifecycle state. Use the signed P ## 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/tree/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/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/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/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/tree/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/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/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/benchmark/effectbench/task_pack/manifest.json): Effect-verification benchmark task pack manifest used by the flow qualification harness. diff --git a/llms-full.txt b/llms-full.txt index 05a1ee7a21..97679a6746 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -2253,6 +2253,8 @@ Shadow mode checks the writes of an agent you already run against the system of ### Features +- Self-repair's new clicks no longer need a browser. On a backend with an accessibility tree, a click with no record identity under it is admitted when its element (role, name, ancestry, window) is the only one with that locator in the pinned window and a record check covers every save: a system-of-record verifier, a `standard` or `regulated` profile, and confirmed effects and an armed identity check on each save. On a pixel-only backend the record check alone admits it. The new step carries the dialog around it as its identity band, a screen pre-check, and only a person approves such a fix; a signed standard change can't. The browser rule is unchanged. `MacOSBackend.element_identity_at` reads the AX element, the repair hold answers `element_identity`, and agent teach takes the dialog box from it. Design: `docs/REPAIR_ON_EVERY_BACKEND.md` ([#1709](https://github.com/OpenAdaptAI/OpenAdapt/pull/1709)). + - Shadow mode: `openadapt shadow` runs beside an agent you already have, as a loopback pass-through proxy, and checks each write it makes against the system of record (`CONFIRMED`, `REFUTED`, `UNCERTAIN`). It never blocks, changes or resends a write; the only delay is the read before a write, at most `hold_ms`, measured per write. FHIR writes are checked by `ensure_record.verify_ensure` and SQL writes by `verifier.begin_write`/`verify_write` with the whole-database frame. Each `CONFIRMED` is checked again later (`recheck_s`, or the contract's `recheck_after_s`), and a late `REFUTED` gets its own line in `report.html` and `report.json`. `verify_ensure` takes `declared`: resources of other writes the caller saw, judged on their own ([#1678](https://github.com/OpenAdaptAI/OpenAdapt/pull/1678)). - The whole-database frame (`frame.database`) and its recheck now work on PostgreSQL (`dialect: postgresql`). The snapshot is one read-only repeatable-read transaction over every schema but the system ones. Every column type is read as text by a declared rule, in a session pinned to UTC and exact float output: `numeric` at full precision (with its stored scale when it has no declared one), floats exactly, `bytea` as hex, `json` as stored and `jsonb` canonical, arrays, ranges, enums, domains, `uuid`, network, time, `interval`, `money`, bit, `xml`, text-search and geometric types. A table without a primary key is keyed by the whole row, with duplicates counted. A column type without a rule, a table the account can't read in full (no `SELECT`, row-level security), a foreign table and an unreadable sequence are refused unless the allow-list skips them with a reason. A sequence a column owns is that table's counter, and a counter set back counts as a change; any other sequence is compared as a one-row table. Large objects are read by the SHA-256 of their content. `frame.database.schemas` means the same as on MySQL (each must be visible, and every visible schema is read); a schema is left out only by an `allow_tables` entry `.*` with `mode: skip` and a reason. diff --git a/openadapt/cli.py b/openadapt/cli.py index 6c046d70a9..d8ca1a1bce 100644 --- a/openadapt/cli.py +++ b/openadapt/cli.py @@ -848,9 +848,9 @@ def _warn_about_launcher_conflicts() -> None: _SECRET_REFERENCE = re.compile(r"^(?:env:[A-Z][A-Z0-9_]*|keychain:[^/\s]+/[^/\s]+)$") # Flow 1.33 and 1.34 probe four X11 libraries in the wrong case, so on Linux # they refuse to download Chromium on hosts that have them. 1.35.0 fixed it. -# Launcher 1.18 requires Flow 2.2: the quickstart uses its offline Seals, -# shared browser and OCR prewarm. -_SUPPORTED_FLOW_RANGE = ">=2.2.0,<3.0.0" +# Launcher 1.19 requires Flow 2.5: `openadapt shadow` forwards to its shadow +# command, and `openadapt verify serve` offers its recheck. +_SUPPORTED_FLOW_RANGE = ">=2.5.0,<3.0.0" _RDP_INSTALL_COMMAND = _pip_install("openadapt[rdp]") _CHROMIUM_SYSTEM_LIBS_COMMAND = ( f"{shlex.quote(sys.executable)} -m playwright install-deps chromium" @@ -860,7 +860,7 @@ def _warn_about_launcher_conflicts() -> None: def _supported_flow_version(value: str) -> bool: """Return whether a stable Flow version is in the launcher's supported range.""" parsed = _release_tuple(value) - return parsed is not None and (2, 2, 0) <= parsed < (3, 0, 0) + return parsed is not None and (2, 5, 0) <= parsed < (3, 0, 0) # The Python modules each native or remote Flow backend imports when its diff --git a/platform-manifest.json b/platform-manifest.json index de4b51e526..a59c049229 100644 --- a/platform-manifest.json +++ b/platform-manifest.json @@ -1,7 +1,7 @@ { "manifest_kind": "openadapt-platform-release-manifest", "schema_version": "2.0.0", - "generated_at": "2026-10-20T17:25:50+00:00", + "generated_at": "2026-11-03T00:23:35+00:00", "generation": { "files": [ { @@ -20,7 +20,7 @@ "agent": "2.2.1", "capture": "1.2.2", "desktop": "0.16.0", - "flow": "2.3.0", + "flow": "2.5.0", "launcher": "1.17.0", "privacy": "1.1.2", "types": "0.24.0" @@ -306,7 +306,7 @@ }, "flow": { "package": "openadapt-flow", - "version": "2.3.0", + "version": "2.5.0", "source": "pypi", "requires_python": "<3.13,>=3.10", "requires": { @@ -351,24 +351,24 @@ ], "provenance": { "repository": "OpenAdaptAI/OpenAdapt", - "release_ref": "openadapt-flow-v2.3.0", - "commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", - "tree": "14bf88ccefe00708bb51003d6262876c555e7271", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/tree/openadapt-flow-v2.3.0/packages/flow", + "release_ref": "openadapt-flow-v2.5.0", + "commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", + "tree": "cab536c90e79fcfe887b8876e884ec2ed651f23e", + "url": "https://github.com/OpenAdaptAI/OpenAdapt/tree/openadapt-flow-v2.5.0/packages/flow", "source_root": "packages/flow" }, "artifacts": [ { "type": "bdist_wheel", - "filename": "openadapt_flow-2.3.0-py3-none-any.whl", - "url": "https://files.pythonhosted.org/packages/01/a7/915b9d0110da17393741e60d0c19574f7a14c9ca54c1a9e5a13af2b15280/openadapt_flow-2.3.0-py3-none-any.whl", - "sha256": "6a2dbd22eb15bd449fc12a6dc36dcc8da7c0316f9faac80cbff8d6e9a433222b" + "filename": "openadapt_flow-2.5.0-py3-none-any.whl", + "url": "https://files.pythonhosted.org/packages/7d/7b/76f2027c37fd059c0c1409cd6ca6c995da13fc5891c40b138f9b0cf1362f/openadapt_flow-2.5.0-py3-none-any.whl", + "sha256": "1dbc5d42d103cfa8a452d95805dde60c7d460035ec4d81df5cc642a32f118339" }, { "type": "sdist", - "filename": "openadapt_flow-2.3.0.tar.gz", - "url": "https://files.pythonhosted.org/packages/08/81/a557d7472ebd192992fe37bd9493bb998941f6af5b0258a95403c4634dc5/openadapt_flow-2.3.0.tar.gz", - "sha256": "39f3b853987227063257a1ffcd402ca3a3120e508d901578622cd0351f1ce12d" + "filename": "openadapt_flow-2.5.0.tar.gz", + "url": "https://files.pythonhosted.org/packages/b3/9e/c4b87cfdba0b1ae03d57062bad41686cb9b3affd46e901ee1749fcf1e5b8/openadapt_flow-2.5.0.tar.gz", + "sha256": "54d99e77976ee7d9e6bc171b2ea148497528ead77b226fdf6fd4713b37c689b3" } ] }, @@ -613,20 +613,20 @@ }, "selected": { "openadapt": "1.17.0", - "openadapt-flow": "2.3.0" + "openadapt-flow": "2.5.0" } }, "customer_runner": { "kind": "customer-controlled-runner", - "version": "2.3.0", + "version": "2.5.0", "source_component": "flow", "entry_point": "openadapt-flow", "requirements": { - "openadapt-flow": "==2.3.0", + "openadapt-flow": "==2.5.0", "openadapt-types": "<0.25.0,>=0.24.0" }, "selected": { - "openadapt-flow": "2.3.0", + "openadapt-flow": "2.5.0", "openadapt-types": "0.24.0" } }, @@ -662,7 +662,7 @@ }, "selected": { "openadapt-agent": "2.2.1", - "openadapt-flow": "2.3.0" + "openadapt-flow": "2.5.0" } } }, @@ -739,7 +739,7 @@ "target_role": "flow", "target_package": "openadapt-flow", "requires": "<3,>=2.2.0", - "resolved": "2.3.0", + "resolved": "2.5.0", "activations": [ { "extras": null, @@ -791,7 +791,7 @@ "scope": "selected-platform", "source_role": "flow", "source_package": "openadapt-flow", - "source_version": "2.3.0", + "source_version": "2.5.0", "target_role": "capture", "target_package": "openadapt-capture", "requires": ">=1.2.0", @@ -807,7 +807,7 @@ "scope": "selected-platform", "source_role": "flow", "source_package": "openadapt-flow", - "source_version": "2.3.0", + "source_version": "2.5.0", "target_role": "privacy", "target_package": "openadapt-privacy", "requires": ">=1.0.0", @@ -823,7 +823,7 @@ "scope": "selected-platform", "source_role": "flow", "source_package": "openadapt-flow", - "source_version": "2.3.0", + "source_version": "2.5.0", "target_role": "types", "target_package": "openadapt-types", "requires": "<0.25.0,>=0.24.0", @@ -891,7 +891,7 @@ "target_role": "flow", "target_package": "openadapt-flow", "requires": "<3.0.0,>=2.0.0", - "resolved": "2.3.0", + "resolved": "2.5.0", "activations": [ { "extras": null, @@ -979,19 +979,19 @@ ], "minimum": 1, "maximum": 2, - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_files": [ { "path": "packages/flow/openadapt_flow/bundle_validation.py", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/bundle_validation.py", - "git_blob": "2c8143baabcf53f7fb2b8fea7dcf75794d60e38f", - "sha256": "936c42daa7618a07222a6807080045aa5e8a25ebcf4dd2c7488351fc13663d18" + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/bundle_validation.py", + "git_blob": "78c30442341699d497d934699154a72fe213791d", + "sha256": "63532fb8e49f25a8aba8dccca505362a9293b8db9cbc0f2904dd8f9a6e23fea8" }, { "path": "packages/flow/openadapt_flow/ir.py", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/ir.py", - "git_blob": "aee7c6ba869c0b8db388d83bd6953ae44d31e577", - "sha256": "739fe7f4841a018668840559cead446d25c6a22d1a33ed3721bd553d10e9366a" + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/ir.py", + "git_blob": "fd235efbebf639c3f047eb0ca7421115733cfb85", + "sha256": "efb7fdce6fa625f631901389ca767b016f4db3111caa2905321ff3da675e376d" } ] }, @@ -1108,11 +1108,11 @@ ], "minimum": 2, "maximum": 2, - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_files": [ { "path": "packages/flow/openadapt_flow/console/decision_relay.py", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/console/decision_relay.py", + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/console/decision_relay.py", "git_blob": "297d2f71727f83496221091a4237d704c25665d6", "sha256": "d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292" } @@ -1126,11 +1126,11 @@ ], "minimum": 1, "maximum": 1, - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_files": [ { "path": "packages/flow/openadapt_flow/console/human_decisions.py", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/console/human_decisions.py", + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/console/human_decisions.py", "git_blob": "caaf87396aca4770eace5eead3fdf6515e31fbfc", "sha256": "02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477" } @@ -1146,11 +1146,11 @@ ], "minimum": 1, "maximum": 3, - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_files": [ { "path": "packages/flow/openadapt_flow/runtime_validation.py", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/openadapt_flow/runtime_validation.py", + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/openadapt_flow/runtime_validation.py", "git_blob": "fd6121209e50abcab41bb8b70f95ff2647d9303f", "sha256": "a5a220f570c5ee5769ac2f21d8d140bb69373d4de2ccc0ebfd08540122883f0e" } @@ -1170,7 +1170,7 @@ ">=0.1.0" ], "openadapt-flow": [ - ">=2.2.0,<3.0.0" + ">=2.5.0,<3.0.0" ], "openadapt-grounding": [ ">=0.1.0" @@ -1236,10 +1236,10 @@ "repository": "OpenAdaptAI/OpenAdapt", "path": "packages/flow/public-demo/evidence-packs", "description": "Versioned public evidence packs with per-pack manifest files, replay evidence, and fault-case results.", - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_object_type": "tree", "source_object_sha": "2eac2252f62349e873b461866546dd0295169a19", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/tree/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/public-demo/evidence-packs" + "url": "https://github.com/OpenAdaptAI/OpenAdapt/tree/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/public-demo/evidence-packs" }, { "id": "flow-effectbench-task-pack", @@ -1248,10 +1248,10 @@ "repository": "OpenAdaptAI/OpenAdapt", "path": "packages/flow/benchmark/effectbench/task_pack/manifest.json", "description": "Effect-verification benchmark task pack manifest used by the flow qualification harness.", - "source_commit": "b6a9d46b00b92454c18e844f0a8f6929330e87b6", + "source_commit": "5a3bf49a0bf2d662430386295a1c34036c064d58", "source_object_type": "blob", "source_object_sha": "1c568d2289342e10e3556c5c46cd08a0e370ac84", - "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/b6a9d46b00b92454c18e844f0a8f6929330e87b6/packages/flow/benchmark/effectbench/task_pack/manifest.json" + "url": "https://github.com/OpenAdaptAI/OpenAdapt/blob/5a3bf49a0bf2d662430386295a1c34036c064d58/packages/flow/benchmark/effectbench/task_pack/manifest.json" } ], "signature": { diff --git a/pyproject.toml b/pyproject.toml index 368b201a23..a59fbe1195 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openadapt" -version = "1.18.0" +version = "1.19.0" description = "Enters approved information into the apps your team already uses, checks that it saved, and stops for a person when something doesn't match." # The package description is README.md with its lifecycle block swapped for a # link to the live record; see hatch_build.py. @@ -59,10 +59,10 @@ dependencies = [ # The quickstart's terminal view (MIT). Pure Python; the engine doesn't # depend on it. Gated like the engine: without it the quickstart can't run. "rich>=13.0.0; python_version < '3.13'", - # Every Flow floor is 2.2.0: the quickstart uses Flow's offline Seals, - # shared browser and OCR prewarm, which 2.0 and 2.1 lack - # (tests/test_flow_floor.py). - "openadapt-flow[browser,hosted]>=2.2.0,<3.0.0; python_version < '3.13'", + # Every Flow floor is 2.5.0: `openadapt shadow` forwards to Flow's shadow + # command, and `openadapt verify serve` offers its recheck, which 2.4 and + # earlier lack (tests/test_flow_floor.py). + "openadapt-flow[browser,hosted]>=2.5.0,<3.0.0; python_version < '3.13'", # Day-1 partner kit: `pip install openadapt` must expose the # `openadapt-agent` command without a second package. 2.1.0 adds Seal checks; # `--bundles`; the bundle-free tutorial `serve --allow-run` needs a later @@ -77,7 +77,7 @@ browser = [ # launcher now selects this Flow contract because the bundled quickstart # uses the browser. OpenAdapt requests Chromium on first browser use after # the host dependency check passes. - "openadapt-flow[browser]>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow[browser]>=2.5.0,<3.0.0; python_version < '3.13'", ] # Local human desktop recording. Flow owns the supported capture adapter # contract; the direct floor prevents an already-installed pre-1.0 Capture @@ -85,22 +85,22 @@ browser = [ # separately provisioned executable, not a Python-package dependency. capture = [ "openadapt-capture>=1.2.0,<2.0.0", - "openadapt-flow[capture]>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow[capture]>=2.5.0,<3.0.0; python_version < '3.13'", ] # Replay substrate dependencies stay separate from capture: recording observes # the human on the local interactive desktop, while replay may target a WAA # agent, a native app, or a remote framebuffer. windows = [ - "openadapt-flow[windows]>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow[windows]>=2.5.0,<3.0.0; python_version < '3.13'", ] macos = [ - "openadapt-flow[macos]>=2.2.0,<3.0.0; sys_platform == 'darwin' and python_version < '3.13'", + "openadapt-flow[macos]>=2.5.0,<3.0.0; sys_platform == 'darwin' and python_version < '3.13'", ] linux = [ - "openadapt-flow[linux]>=2.2.0,<3.0.0; sys_platform == 'linux' and python_version < '3.13'", + "openadapt-flow[linux]>=2.5.0,<3.0.0; sys_platform == 'linux' and python_version < '3.13'", ] rdp = [ - "openadapt-flow[rdp]>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow[rdp]>=2.5.0,<3.0.0; python_version < '3.13'", ] ml = [ "openadapt-ml>=0.2.0", @@ -118,13 +118,13 @@ retrieval = [ "openadapt-retrieval>=0.1.0", ] privacy = [ - "openadapt-flow[privacy]>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow[privacy]>=2.5.0,<3.0.0; python_version < '3.13'", ] # `flow` now ships in the base install (see `dependencies` above). This # extra is kept for backward compatibility so `pip install openadapt[flow]` # and the `all` bundle still resolve. flow = [ - "openadapt-flow>=2.2.0,<3.0.0; python_version < '3.13'", + "openadapt-flow>=2.5.0,<3.0.0; python_version < '3.13'", ] # `openadapt-agent` also ships in the base install. Keep the extra so # `pip install openadapt[agent]` still resolves. diff --git a/tests/test_cli_shell_hints.py b/tests/test_cli_shell_hints.py index ccda94c325..129718ff3c 100644 --- a/tests/test_cli_shell_hints.py +++ b/tests/test_cli_shell_hints.py @@ -95,12 +95,12 @@ def test_deploy_console_hint_is_double_quoted(monkeypatch, supported_python): "importlib.util.find_spec", lambda name, *args: object() if name in present else None, ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.1") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.1") result = CliRunner().invoke(cli_main, ["deploy"]) assert result.exit_code == 0, result.output - assert '"openadapt-flow[console]==2.2.1"' in result.output + assert '"openadapt-flow[console]==2.5.1"' in result.output assert not _UNQUOTED_SPEC.search(result.output), result.output diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index 2dabd01078..91f17f2afc 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -380,29 +380,29 @@ def test_launcher_flow_and_substrate_extras_metadata(): assert ( metadata["dependencies"].count( - f"openadapt-flow[browser,hosted]>=2.2.0,<3.0.0; {supported}" + f"openadapt-flow[browser,hosted]>=2.5.0,<3.0.0; {supported}" ) == 1 ) assert ( metadata["dependencies"].count(f"openadapt-agent>=2.1.0,<3; {supported}") == 1 ) - assert extras["flow"] == [f"openadapt-flow>=2.2.0,<3.0.0; {supported}"] + assert extras["flow"] == [f"openadapt-flow>=2.5.0,<3.0.0; {supported}"] assert extras["agent"] == [f"openadapt-agent>=2.1.0,<3; {supported}"] - assert extras["browser"] == [f"openadapt-flow[browser]>=2.2.0,<3.0.0; {supported}"] - assert extras["privacy"] == [f"openadapt-flow[privacy]>=2.2.0,<3.0.0; {supported}"] + assert extras["browser"] == [f"openadapt-flow[browser]>=2.5.0,<3.0.0; {supported}"] + assert extras["privacy"] == [f"openadapt-flow[privacy]>=2.5.0,<3.0.0; {supported}"] assert extras["capture"] == [ "openadapt-capture>=1.2.0,<2.0.0", - f"openadapt-flow[capture]>=2.2.0,<3.0.0; {supported}", + f"openadapt-flow[capture]>=2.5.0,<3.0.0; {supported}", ] - assert extras["windows"] == [f"openadapt-flow[windows]>=2.2.0,<3.0.0; {supported}"] + assert extras["windows"] == [f"openadapt-flow[windows]>=2.5.0,<3.0.0; {supported}"] assert extras["macos"] == [ - f"openadapt-flow[macos]>=2.2.0,<3.0.0; sys_platform == 'darwin' and {supported}" + f"openadapt-flow[macos]>=2.5.0,<3.0.0; sys_platform == 'darwin' and {supported}" ] assert extras["linux"] == [ - f"openadapt-flow[linux]>=2.2.0,<3.0.0; sys_platform == 'linux' and {supported}" + f"openadapt-flow[linux]>=2.5.0,<3.0.0; sys_platform == 'linux' and {supported}" ] - assert extras["rdp"] == [f"openadapt-flow[rdp]>=2.2.0,<3.0.0; {supported}"] + assert extras["rdp"] == [f"openadapt-flow[rdp]>=2.5.0,<3.0.0; {supported}"] assert extras["all"] == [ "openadapt[browser,core,grounding,retrieval,privacy,flow,windows,rdp,agent]", "openadapt[macos]; sys_platform == 'darwin'", @@ -433,7 +433,7 @@ def test_released_flow_x11_sonames_are_case_corrected(monkeypatch): ) -@pytest.mark.parametrize("version", ["2.2.0", "2.2.1", "2.99.0"]) +@pytest.mark.parametrize("version", ["2.5.0", "2.5.1", "2.99.0"]) def test_launcher_accepts_flow_versions_in_the_supported_range(version): assert _supported_flow_version(version) @@ -533,7 +533,7 @@ def test_deploy_native_backend_fails_without_its_platform_extra( monkeypatch, backend, host, modules, install ): _host(monkeypatch, host, {"openadapt_flow"}) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", backend]) @@ -550,7 +550,7 @@ def test_deploy_native_backend_passes_with_its_platform_extra( monkeypatch, backend, host, modules, install ): _host(monkeypatch, host, {"openadapt_flow"} | modules) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", backend]) @@ -690,7 +690,7 @@ def test_deploy_preflight_composes_existing_flow_interfaces_without_secrets( else None ), ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") monkeypatch.setenv("BYOC_CONNECTOR_TOKEN", "connector-token-value") result = CliRunner().invoke( cli_main, @@ -715,13 +715,13 @@ def test_deploy_base_hosted_install_gives_conditional_console_setup(monkeypatch) "importlib.util.find_spec", lambda name: object() if name in {"openadapt_flow", "aardwolf"} else None, ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", "rdp"]) assert result.exit_code == 0, result.output assert "optional local operator console is not installed" in result.output - assert 'python -m pip install "openadapt-flow[console]==2.2.0"' in result.output + assert 'python -m pip install "openadapt-flow[console]==2.5.0"' in result.output assert "openadapt flow console --bundles" not in result.output assert "Re-run this preflight" in result.output @@ -736,13 +736,13 @@ def test_deploy_console_requires_openadapt_types(monkeypatch): else None ), ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", "rdp"]) assert result.exit_code == 0, result.output assert "optional local operator console is not installed" in result.output - assert 'python -m pip install "openadapt-flow[console]==2.2.0"' in result.output + assert 'python -m pip install "openadapt-flow[console]==2.5.0"' in result.output assert "openadapt flow console --bundles" not in result.output @@ -767,7 +767,7 @@ def test_deploy_preflight_fails_without_web_runtime(monkeypatch): "importlib.util.find_spec", lambda name: object() if name == "openadapt_flow" else None, ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", "web"]) @@ -785,7 +785,7 @@ def test_deploy_preflight_fails_without_rdp_transport(monkeypatch): "importlib.util.find_spec", lambda name: object() if name == "openadapt_flow" else None, ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") result = CliRunner().invoke(cli_main, ["deploy", "--backend", "rdp"]) @@ -807,7 +807,7 @@ def test_deploy_preflight_fails_for_unsupported_flow(monkeypatch, flow_version): assert result.exit_code != 0 assert "[UNSUPPORTED]" in result.output - assert ">=2.2.0,<3.0.0" in result.output + assert ">=2.5.0,<3.0.0" in result.output assert "Preflight passed" not in result.output diff --git a/tests/test_deploy_preflight_readiness.py b/tests/test_deploy_preflight_readiness.py index b4999cdfd7..d1eef428ad 100644 --- a/tests/test_deploy_preflight_readiness.py +++ b/tests/test_deploy_preflight_readiness.py @@ -29,7 +29,7 @@ def _deploy(monkeypatch, args, installed=READY_WEB, host=None): "importlib.util.find_spec", lambda name: object() if name in installed else None, ) - monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.2.0") + monkeypatch.setattr("importlib.metadata.version", lambda _name: "2.5.0") return CliRunner().invoke(cli_main, ["deploy", *args]) diff --git a/tests/test_flow_floor.py b/tests/test_flow_floor.py index c653c91c3f..751df09bcb 100644 --- a/tests/test_flow_floor.py +++ b/tests/test_flow_floor.py @@ -24,10 +24,10 @@ import tomli as tomllib ROOT = Path(__file__).resolve().parents[1] -# Launcher 1.18 requires Flow 2.2 (the quickstart's offline Seals, shared -# browser and OCR prewarm), so 1.x, 2.0 and 2.1 are below the floor. -BELOW_FLOOR = ["1.29.0", "1.34.9", "1.35.1", "2.0.0", "2.1.0", "2.1.9"] -ACCEPTED = "2.2.0" +# Launcher 1.19 requires Flow 2.5 (`openadapt shadow` and the recheck that +# `openadapt verify serve` offers), so 1.x and 2.0 to 2.4 are below the floor. +BELOW_FLOOR = ["1.29.0", "1.35.1", "2.0.0", "2.2.0", "2.4.1"] +ACCEPTED = "2.5.0" def _flow_requirements() -> list[Requirement]: diff --git a/uv.lock b/uv.lock index 4ff362503c..9b636a0e1b 100644 --- a/uv.lock +++ b/uv.lock @@ -3245,7 +3245,7 @@ wheels = [ [[package]] name = "openadapt" -version = "1.18.0" +version = "1.19.0" source = { editable = "." } dependencies = [ { name = "click" }, @@ -3335,15 +3335,15 @@ requires-dist = [ { name = "openadapt-agent", marker = "python_full_version < '3.13' and extra == 'agent'", specifier = ">=2.1.0,<3" }, { name = "openadapt-capture", marker = "extra == 'capture'", specifier = ">=1.2.0,<2.0.0" }, { name = "openadapt-evals", marker = "extra == 'evals'", specifier = ">=0.1.0" }, - { name = "openadapt-flow", marker = "python_full_version < '3.13' and extra == 'flow'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["browser"], marker = "python_full_version < '3.13' and extra == 'browser'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["browser", "hosted"], marker = "python_full_version < '3.13'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["capture"], marker = "python_full_version < '3.13' and extra == 'capture'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["linux"], marker = "python_full_version < '3.13' and sys_platform == 'linux' and extra == 'linux'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["macos"], marker = "python_full_version < '3.13' and sys_platform == 'darwin' and extra == 'macos'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["privacy"], marker = "python_full_version < '3.13' and extra == 'privacy'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["rdp"], marker = "python_full_version < '3.13' and extra == 'rdp'", specifier = ">=2.2.0,<3.0.0" }, - { name = "openadapt-flow", extras = ["windows"], marker = "python_full_version < '3.13' and extra == 'windows'", specifier = ">=2.2.0,<3.0.0" }, + { name = "openadapt-flow", marker = "python_full_version < '3.13' and extra == 'flow'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["browser"], marker = "python_full_version < '3.13' and extra == 'browser'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["browser", "hosted"], marker = "python_full_version < '3.13'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["capture"], marker = "python_full_version < '3.13' and extra == 'capture'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["linux"], marker = "python_full_version < '3.13' and sys_platform == 'linux' and extra == 'linux'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["macos"], marker = "python_full_version < '3.13' and sys_platform == 'darwin' and extra == 'macos'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["privacy"], marker = "python_full_version < '3.13' and extra == 'privacy'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["rdp"], marker = "python_full_version < '3.13' and extra == 'rdp'", specifier = ">=2.5.0,<3.0.0" }, + { name = "openadapt-flow", extras = ["windows"], marker = "python_full_version < '3.13' and extra == 'windows'", specifier = ">=2.5.0,<3.0.0" }, { name = "openadapt-grounding", marker = "extra == 'grounding'", specifier = ">=0.1.0" }, { name = "openadapt-ml", marker = "extra == 'ml'", specifier = ">=0.2.0" }, { name = "openadapt-retrieval", marker = "extra == 'retrieval'", specifier = ">=0.1.0" }, @@ -3437,7 +3437,7 @@ wheels = [ [[package]] name = "openadapt-flow" -version = "2.3.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, @@ -3452,9 +3452,9 @@ dependencies = [ { name = "rapidocr-onnxruntime" }, { name = "tomli", marker = "python_full_version < '3.11' or python_full_version >= '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/81/a557d7472ebd192992fe37bd9493bb998941f6af5b0258a95403c4634dc5/openadapt_flow-2.3.0.tar.gz", hash = "sha256:39f3b853987227063257a1ffcd402ca3a3120e508d901578622cd0351f1ce12d", size = 27680059, upload-time = "2026-10-20T17:21:13.302Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/9e/c4b87cfdba0b1ae03d57062bad41686cb9b3affd46e901ee1749fcf1e5b8/openadapt_flow-2.5.0.tar.gz", hash = "sha256:54d99e77976ee7d9e6bc171b2ea148497528ead77b226fdf6fd4713b37c689b3", size = 31358408, upload-time = "2026-11-03T00:16:39.944Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/a7/915b9d0110da17393741e60d0c19574f7a14c9ca54c1a9e5a13af2b15280/openadapt_flow-2.3.0-py3-none-any.whl", hash = "sha256:6a2dbd22eb15bd449fc12a6dc36dcc8da7c0316f9faac80cbff8d6e9a433222b", size = 3783372, upload-time = "2026-10-20T17:21:10.135Z" }, + { url = "https://files.pythonhosted.org/packages/7d/7b/76f2027c37fd059c0c1409cd6ca6c995da13fc5891c40b138f9b0cf1362f/openadapt_flow-2.5.0-py3-none-any.whl", hash = "sha256:1dbc5d42d103cfa8a452d95805dde60c7d460035ec4d81df5cc642a32f118339", size = 4335676, upload-time = "2026-11-03T00:16:37.35Z" }, ] [package.optional-dependencies]