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]