Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/quickstart-lifecycle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
python scripts/quickstart_lifecycle.py
--launcher-wheel "lifecycle-dist/*.whl"
--work-dir "runs/launcher-lifecycle"
--browser-with-deps
--browser-system-deps
--source-revision "${{ github.sha }}"

- name: Upload lifecycle evidence
Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,27 @@ the run tool:

```bash
python -m pip install --upgrade openadapt
openadapt doctor --backend web
openadapt flow tutorial
openadapt-agent serve --allow-run
```

Python 3.10 through 3.12. No account, no API key, no extra. Chromium downloads
itself the first time a browser action runs. `openadapt-agent` is in the base
install.
Python 3.10 through 3.12. The local tutorial needs no account or API key. The
base install includes Playwright and `openadapt-agent`. On the first browser
action, OpenAdapt asks Playwright to download its matching Chromium build. That
download needs network access.

Minimal Linux hosts can lack Chromium's shared libraries. `openadapt doctor`
lists the missing libraries before any browser download. If it finds any, run:

```bash
python -m playwright install-deps chromium
openadapt doctor --backend web
```

Playwright asks for administrator access when the package manager needs it.
Use the interpreter-specific command from `doctor` if you installed OpenAdapt
with an isolated tool runner.

`openadapt flow tutorial` is the launcher spelling of `openadapt-flow tutorial`.
It records and compiles a task in MockMed, a synthetic practice-management
Expand Down
22 changes: 19 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,25 @@ openadapt doctor --backend web
openadapt deploy --backend web
```

`doctor` checks the local capability dependencies. `deploy` performs a
read-only deployment preflight and prints the applicable Flow and Desktop
path. Neither command certifies a customer workflow.
`doctor` checks the required launcher packages. For the default and `web`
checks, it also uses Flow's Chromium library probe. A missing core package or
Chromium system library returns a nonzero exit status. On Linux, install missing
browser libraries with:

```bash
python -m playwright install-deps chromium
```

Playwright asks for administrator access when the package manager needs it.
The command printed by `doctor` uses the exact Python interpreter that runs the
launcher, including an interpreter inside an isolated tool environment.

An absent Chromium binary does not fail the check when its host libraries are
ready. OpenAdapt will ask Playwright to download the matching build on the first
browser action, so that action needs network access.

`deploy` performs a read-only deployment preflight and prints the applicable
Flow and Desktop path. Neither command certifies a customer workflow.

## Hosted connection

Expand Down
23 changes: 19 additions & 4 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,26 @@ Install the launcher:

```bash
python -m pip install --upgrade openadapt
openadapt doctor --backend web
openadapt flow tutorial
```

The launcher installs the compatible `openadapt-flow` engine. Do not install
the launcher and engine separately. The first browser action downloads the
matching Chromium build once.
the launcher and engine separately. On the first browser action, OpenAdapt asks
Playwright to download its matching Chromium build. The download needs network
access.

On Linux, `doctor` checks Chromium's system libraries before that download. If
it lists missing libraries, install them and run the check again:

```bash
python -m playwright install-deps chromium
openadapt doctor --backend web
```

Playwright asks for administrator access when the package manager needs it.
Use the interpreter-specific command from `doctor` if an isolated tool runner
installed OpenAdapt.

The tutorial uses the bundled synthetic MockMed application. It records,
compiles, certifies, and replays one workflow. A separate read-only interface
Expand All @@ -28,8 +42,9 @@ profile with no model or Cloud call.
## Capability-specific installs

The base install includes the launcher, the Flow engine, and the Playwright
driver for the browser tutorial. Chromium downloads only on the first browser
action. Add the applicable capability for a native or remote workflow:
driver for the browser tutorial. OpenAdapt requests the Chromium download only
when a browser action needs it. Add the applicable capability for a native or
remote workflow:

```bash
python -m pip install 'openadapt[capture]' # local human demonstration
Expand Down
96 changes: 84 additions & 12 deletions openadapt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import platform
import re
import shlex
import sys
from pathlib import Path
from typing import Optional
Expand Down Expand Up @@ -88,6 +89,28 @@ def main():
# Flow Commands (the demonstration compiler — flagship path)
# =============================================================================

_FLOW_X11_SONAME_CASE = {
"xcomposite": "Xcomposite",
"xdamage": "Xdamage",
"xfixes": "Xfixes",
"xrandr": "Xrandr",
}


def _correct_released_flow_x11_sonames() -> None:
"""Correct the four case-sensitive X11 probes in released Flow builds."""
if sys.platform != "linux":
return
try:
import openadapt_flow._browser_setup as browser_setup
except ImportError:
return
sonames = getattr(browser_setup, "_LINUX_CHROMIUM_SONAMES", None)
if not isinstance(sonames, (list, tuple)):
return
corrected = tuple(_FLOW_X11_SONAME_CASE.get(name, name) for name in sonames)
browser_setup._LINUX_CHROMIUM_SONAMES = corrected


def _invoke_flow(argv: list[str]) -> int:
"""Invoke the canonical engine once and return its exit code."""
Expand All @@ -99,6 +122,7 @@ def _invoke_flow(argv: list[str]) -> int:
click.echo("Engine only: pip install openadapt-flow", err=True)
return 1

_correct_released_flow_x11_sonames()
return int(flow_main(argv))


Expand Down Expand Up @@ -283,6 +307,9 @@ def quickstart(
_SECRET_REFERENCE = re.compile(r"^(?:env:[A-Z][A-Z0-9_]*|keychain:[^/\s]+/[^/\s]+)$")
_SUPPORTED_FLOW_RANGE = ">=1.29.0,<2.0.0"
_RDP_INSTALL_COMMAND = "python -m pip install 'openadapt[rdp]'"
_CHROMIUM_SYSTEM_LIBS_COMMAND = (
f"{shlex.quote(sys.executable)} -m playwright install-deps chromium"
)


def _supported_flow_version(value: str) -> bool:
Expand Down Expand Up @@ -1045,24 +1072,68 @@ def doctor(backend: str | None):
else:
playwright = find_spec("playwright") is not None
if not playwright:
failures.append("playwright")
click.echo(
" [MISSING] Browser: the base install does not contain "
"Playwright. Run `python -m pip install --upgrade openadapt`."
)
else:
_correct_released_flow_x11_sonames()
try:
from openadapt_flow._browser_setup import _chromium_present

chromium = _chromium_present()
except Exception:
chromium = False
if chromium:
click.echo(" [OK] Browser: Playwright and Chromium are ready.")
else:
from openadapt_flow._browser_setup import (
_chromium_present,
_missing_chromium_system_libs,
)
except (ImportError, AttributeError):
failures.append("browser-diagnostics")
click.echo(
" [READY] Browser: Playwright is installed; the matching "
"Chromium downloads automatically on the first web action."
" [MISSING] Browser: the installed Flow version cannot check "
"Chromium dependencies. Run `python -m pip install --upgrade "
"openadapt`."
)
else:
try:
missing_system_libs = _missing_chromium_system_libs()
except Exception:
failures.append("browser-system-library-check")
click.echo(
" [ERROR] Browser: OpenAdapt could not check Chromium's "
"system libraries. Reinstall OpenAdapt, then run this "
"command again."
)
else:
if missing_system_libs:
failures.append("browser-system-libraries")
click.echo(
" [MISSING] Browser: Chromium needs these system "
f"libraries: {', '.join(missing_system_libs)}"
)
click.echo(
" Install them once: " + _CHROMIUM_SYSTEM_LIBS_COMMAND
)
else:
try:
chromium = _chromium_present()
except Exception:
failures.append("chromium-check")
click.echo(
" [ERROR] Browser: OpenAdapt could not inspect "
"the installed Chromium build. Reinstall "
"OpenAdapt, then run this command again."
)
else:
if chromium:
click.echo(
" [OK] Browser: Playwright, Chromium, and its "
"system libraries are ready."
)
else:
click.echo(
" [READY] Browser: Playwright and Chromium's "
"system libraries are ready. OpenAdapt will try "
"to download the matching Chromium build on the "
"first web action."
)

# Core packages: installed by the base `pip install openadapt`. Only
# these are treated as required; a missing one is a real problem.
Expand All @@ -1079,8 +1150,9 @@ def doctor(backend: str | None):
if find_spec(pkg) is not None:
click.echo(f" [OK] {pkg}")
else:
failures.append(f"core:{pkg}")
click.echo(
f" [MISSING] {pkg} (core dependency reinstall with "
f" [MISSING] {pkg} (core dependency; reinstall with "
f"`pip install openadapt`)"
)

Expand All @@ -1102,7 +1174,7 @@ def doctor(backend: str | None):
click.echo(f" [OK] {pkg}")
else:
click.echo(
f" [--] {pkg} (optional install with "
f" [--] {pkg} (optional; install with "
f"`pip install openadapt[{extra}]`)"
)

Expand Down
8 changes: 4 additions & 4 deletions production-lifecycle-source.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"schema_version": "openadapt.production-readme-source/v1",
"repository": "OpenAdaptAI/openadapt-ops",
"source_commit": "9e7bec32d9165a075828f28f00aa27888b775db4",
"source_commit": "db99c71dc3e105d0bd74f0a1e8aa0ee0464e18ee",
"files": {
"projection": {
"path": "docs/production-lifecycle.json",
"url": "https://raw.githubusercontent.com/OpenAdaptAI/openadapt-ops/9e7bec32d9165a075828f28f00aa27888b775db4/docs/production-lifecycle.json",
"sha256": "sha256:0fedb6fa123646ce779d0ed68a1d2e34acb3f0d0806fa123842ea18093f59a58"
"url": "https://raw.githubusercontent.com/OpenAdaptAI/openadapt-ops/db99c71dc3e105d0bd74f0a1e8aa0ee0464e18ee/docs/production-lifecycle.json",
"sha256": "sha256:da7d59c495ae503f7a15329a6375276ced7b5a6fe606bffa560bd077eb58491b"
},
"schema": {
"path": "docs/schemas/production-lifecycle-public.schema.json",
"url": "https://raw.githubusercontent.com/OpenAdaptAI/openadapt-ops/9e7bec32d9165a075828f28f00aa27888b775db4/docs/schemas/production-lifecycle-public.schema.json",
"url": "https://raw.githubusercontent.com/OpenAdaptAI/openadapt-ops/db99c71dc3e105d0bd74f0a1e8aa0ee0464e18ee/docs/schemas/production-lifecycle-public.schema.json",
"sha256": "sha256:c6db48d6089314d745c2cf1af7bced511f359c7fee9cacc2e35b758fc22d7073"
}
}
Expand Down
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ classifiers = [
# Base install: the CLI, the flagship demonstration compiler, and the browser
# driver used by the bundled tutorial. `pip install openadapt` must make the
# public `openadapt quickstart` command work without a second package install.
# Playwright downloads Chromium lazily on the first browser action. All other
# capabilities (capture, ml, evals, ...) remain opt-in extras.
# OpenAdapt asks Playwright to download Chromium on the first browser action.
# Linux system libraries remain host prerequisites; `openadapt doctor` and Flow
# check them before the browser download. All other capabilities (capture, ml,
# evals, ...) remain opt-in extras.
dependencies = [
"click>=8.0.0",
"openadapt-flow[browser,hosted]>=1.29.0,<2.0.0",
Expand All @@ -45,7 +47,8 @@ dependencies = [
browser = [
# Kept as a compatibility alias for existing install commands. The base
# launcher now selects this Flow contract because the bundled quickstart
# uses the browser. Chromium remains lazy on first use.
# uses the browser. OpenAdapt requests Chromium on first browser use after
# the host dependency check passes.
"openadapt-flow[browser]>=1.29.0,<2.0.0",
]
# Local human desktop recording. Flow owns the supported capture adapter
Expand Down
Loading