openadapt-agent 2.2.0__tar.gz → 2.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openadapt_agent-2.2.1/CHANGELOG.md +13 -0
- openadapt_agent-2.2.0/README.md → openadapt_agent-2.2.1/PKG-INFO +91 -36
- openadapt_agent-2.2.0/PKG-INFO → openadapt_agent-2.2.1/README.md +54 -73
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/docs/DESIGN.md +20 -6
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/docs/DISTRIBUTION.md +5 -5
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/docs/MAILBOX_CLI.md +1 -1
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/docs/REPAIR.md +1 -1
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/docs/examples/sandbox-results.json +1 -1
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/manifest.json +3 -3
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/pyproject.toml +7 -7
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/smoke_client.py +1 -2
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/server.json +5 -4
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/skills/openadapt-gui-write/SKILL.md +3 -5
- openadapt_agent-2.2.1/src/openadapt_agent/__init__.py +66 -0
- openadapt_agent-2.2.1/src/openadapt_agent/mcpb_entry.py +6 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_approval.py +44 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_authoring.py +48 -12
- openadapt_agent-2.2.1/tests/test_authoring_native.py +229 -0
- openadapt_agent-2.2.1/tests/test_delegated_approval.py +157 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_distribution.py +29 -11
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_mailbox.py +4 -4
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_mcpb_entry.py +1 -1
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_public_lifecycle.py +1 -1
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_readme_commands.py +1 -1
- openadapt_agent-2.2.1/tests/test_repair_branch.py +73 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_sandbox.py +4 -4
- openadapt_agent-2.2.1/tests/test_shim.py +37 -0
- openadapt_agent-2.2.0/llms.txt +0 -65
- openadapt_agent-2.2.0/src/openadapt_agent/__init__.py +0 -26
- openadapt_agent-2.2.0/src/openadapt_agent/__main__.py +0 -6
- openadapt_agent-2.2.0/src/openadapt_agent/approval.py +0 -124
- openadapt_agent-2.2.0/src/openadapt_agent/attended.py +0 -427
- openadapt_agent-2.2.0/src/openadapt_agent/authoring.py +0 -1689
- openadapt_agent-2.2.0/src/openadapt_agent/bridge.py +0 -860
- openadapt_agent-2.2.0/src/openadapt_agent/bundles.py +0 -245
- openadapt_agent-2.2.0/src/openadapt_agent/cards.py +0 -346
- openadapt_agent-2.2.0/src/openadapt_agent/cli.py +0 -769
- openadapt_agent-2.2.0/src/openadapt_agent/contract.py +0 -926
- openadapt_agent-2.2.0/src/openadapt_agent/copy.py +0 -53
- openadapt_agent-2.2.0/src/openadapt_agent/flow_service.py +0 -51
- openadapt_agent-2.2.0/src/openadapt_agent/mailbox.py +0 -806
- openadapt_agent-2.2.0/src/openadapt_agent/mcp.py +0 -411
- openadapt_agent-2.2.0/src/openadapt_agent/mcpb_entry.py +0 -66
- openadapt_agent-2.2.0/src/openadapt_agent/repair.py +0 -724
- openadapt_agent-2.2.0/src/openadapt_agent/runner.py +0 -941
- openadapt_agent-2.2.0/src/openadapt_agent/runner_bind.py +0 -185
- openadapt_agent-2.2.0/src/openadapt_agent/runs.py +0 -381
- openadapt_agent-2.2.0/src/openadapt_agent/sandbox.py +0 -512
- openadapt_agent-2.2.0/src/openadapt_agent/seal.py +0 -210
- openadapt_agent-2.2.0/src/openadapt_agent/seal_cli.py +0 -276
- openadapt_agent-2.2.0/src/openadapt_agent/service.py +0 -556
- openadapt_agent-2.2.0/src/openadapt_agent/skill.py +0 -188
- openadapt_agent-2.2.0/src/openadapt_agent/tutorial.py +0 -169
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/CODEOWNERS +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/dependabot.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/workflows/ci.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/workflows/codeql.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/workflows/dependency-review.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/workflows/release.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.github/workflows/secret-scan.yml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.gitignore +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.gitleaks.toml +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/.mcpbignore +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/LICENSE +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/SECURITY.md +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/capture_sandbox_examples.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/check_dist.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/check_mcpb.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/check_release_artifacts.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/scripts/check_source_boundary.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/source-policy.public.json +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/conftest.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/fixtures/cloud-ts-signed-seal.json +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_approval_flow.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_attended_bridge.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_bridge.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_cards.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_cli.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_contract.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_mcp_server.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_partner_kit.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_repair.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_repair_e2e.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_repair_hold.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_runner.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_runs.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_sandbox_flow.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_seal.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_seal_cli.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_seal_e2e.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_service.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_skill.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/tests/test_tutorial.py +0 -0
- {openadapt_agent-2.2.0 → openadapt_agent-2.2.1}/uv.lock +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
Releases up to v2.2.0 are recorded in the [openadapt-agent repository](https://github.com/OpenAdaptAI/openadapt-agent/blob/main/CHANGELOG.md).
|
|
4
|
+
|
|
5
|
+
## v2.2.1 (2026-10-18)
|
|
6
|
+
|
|
7
|
+
First release from the [OpenAdapt monorepo](https://github.com/OpenAdaptAI/OpenAdapt) (`packages/agent`). The MCP agent server now lives in `openadapt_flow.agent`; this package is a compatibility package over it, so `openadapt-agent` and `import openadapt_agent` keep working. It requires `openadapt-flow>=2.2.0,<3`.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- The server reads the approval mode and can answer a waiting save as a delegated agent ([#1192](https://github.com/OpenAdaptAI/OpenAdapt/pull/1192)).
|
|
12
|
+
- After a step is repaired more than once, the server proposes a branch ([#1188](https://github.com/OpenAdaptAI/OpenAdapt/pull/1188)).
|
|
13
|
+
- The install docs use user scope and say what happens next ([#1230](https://github.com/OpenAdaptAI/OpenAdapt/pull/1230)).
|
|
@@ -1,7 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openadapt-agent
|
|
3
|
+
Version: 2.2.1
|
|
4
|
+
Summary: Let your AI agent enter information in apps with no API and get back whether it saved (MCP and Agent Skills)
|
|
5
|
+
Project-URL: Homepage, https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/agent
|
|
6
|
+
Project-URL: Repository, https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/agent
|
|
7
|
+
Project-URL: Documentation, https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/agent/README.md
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/OpenAdaptAI/OpenAdapt/issues
|
|
9
|
+
Author-email: Richard Abrich <richard@openadapt.ai>
|
|
10
|
+
Maintainer-email: OpenAdaptAI <contact@openadapt.ai>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agent-skills,ai-agents,automation,ehr,gui,mcp,openadapt,rpa,workflow
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: <3.13,>=3.10
|
|
23
|
+
Requires-Dist: anyio>=4.0
|
|
24
|
+
Requires-Dist: cryptography>=50.0.0
|
|
25
|
+
Requires-Dist: jsonschema>=4.20.0
|
|
26
|
+
Requires-Dist: mcp<3,>=1.28
|
|
27
|
+
Requires-Dist: openadapt-flow<3,>=2.2.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build>=1.2.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
32
|
+
Provides-Extra: repair-screens
|
|
33
|
+
Requires-Dist: openadapt-privacy[presidio]>=1.1.2; extra == 'repair-screens'
|
|
34
|
+
Provides-Extra: tutorial
|
|
35
|
+
Requires-Dist: openadapt-flow[browser,macos]<3,>=2.2.0; extra == 'tutorial'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
1
38
|
# OpenAdapt Agent
|
|
2
39
|
|
|
3
|
-
[](https://github.com/OpenAdaptAI/OpenAdapt/actions/workflows/packages.yml)
|
|
41
|
+
[](https://pypi.org/project/openadapt-agent/)
|
|
42
|
+
[](https://pypi.org/project/openadapt-agent/)
|
|
43
|
+
[](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/agent/LICENSE)
|
|
5
44
|
|
|
6
45
|
Your AI agent decides what to enter. OpenAdapt enters it in the app and checks that it saved.
|
|
7
46
|
|
|
@@ -53,28 +92,30 @@ flowchart LR
|
|
|
53
92
|
|
|
54
93
|
| You build | OpenAdapt provides |
|
|
55
94
|
| --- | --- |
|
|
56
|
-
| The agent that reads documents and decides what to enter | A workflow
|
|
95
|
+
| The agent that reads documents and decides what to enter | A workflow learned from one or more demonstrations in the real app, where a person or an agent shows the task |
|
|
57
96
|
| The call to `run_workflow`, with your own `request_id` | The run on your customer's computer, with a right-record check before it types and a record check after it saves |
|
|
58
97
|
| What your product does with each outcome | One result per request, and no second entry when your agent repeats a `request_id` |
|
|
59
98
|
| Your tests against the four outcomes | A sandbox that returns each outcome on demand |
|
|
60
99
|
|
|
61
|
-
Your customer provides the computer and a person for runs that stop.
|
|
100
|
+
Your customer provides the computer and a person for runs that stop. A person or an agent shows the task, in web apps, native Windows apps, and over Citrix or remote desktop. A person accepts the result before it runs. See [Record a first workflow](#record-a-first-workflow), or [talk to us](https://openadapt.ai/qualify?why=embed) about setting it up.
|
|
62
101
|
|
|
63
102
|
## Try it in three steps
|
|
64
103
|
|
|
65
104
|
The sandbox is a practice server that needs no account. It has one workflow, `add_triage_note`, which adds a note to the first referral in MockMed, a test clinic app with made-up patients.
|
|
66
105
|
|
|
67
|
-
You need [Claude Code](https://claude.com/claude-code) (signed in)
|
|
106
|
+
You need [Claude Code](https://claude.com/claude-code) (signed in) and [uv](https://docs.astral.sh/uv/). To use a different client or your own code, see [Connect your own agent](#connect-your-own-agent).
|
|
68
107
|
|
|
69
|
-
1.
|
|
108
|
+
1. Register the sandbox server. `--scope user` makes it available in every folder; without it, Claude Code saves it for the current folder only.
|
|
70
109
|
|
|
71
110
|
```bash
|
|
72
|
-
claude mcp add openadapt -- uvx --python 3.12
|
|
111
|
+
claude mcp add --scope user openadapt -- uvx --python 3.12 openadapt-agent serve
|
|
73
112
|
```
|
|
74
113
|
|
|
75
|
-
|
|
114
|
+
This only registers the server. It prints one line saying the server was added to user config, and nothing else.
|
|
115
|
+
|
|
116
|
+
2. Start Claude Code with `claude`. Claude Code starts the server. Optional: type `/mcp` to check that `openadapt` is connected.
|
|
76
117
|
|
|
77
|
-
3. Ask: "Use OpenAdapt to
|
|
118
|
+
3. Ask: "Use the OpenAdapt sandbox to run add_triage_note with the note 'Synthetic: recheck blood pressure in 2 weeks' and request id demo-0001."
|
|
78
119
|
|
|
79
120
|
Your agent should call `list_workflows`, then `run_workflow` with these arguments:
|
|
80
121
|
|
|
@@ -99,17 +140,17 @@ The result looks like this (some fields left out):
|
|
|
99
140
|
|
|
100
141
|
This install simulates each run without opening MockMed, and every result says so. To watch the real engine do the work, see [Drive MockMed with the real engine](#drive-mockmed-with-the-real-engine).
|
|
101
142
|
|
|
102
|
-
|
|
143
|
+
openadapt-agent installs from PyPI and requires openadapt-flow 2.1.0 or later, which is on PyPI and installs with it. To try unreleased changes, use `--from git+https://github.com/OpenAdaptAI/OpenAdapt#subdirectory=packages/agent` in place of the package name.
|
|
103
144
|
|
|
104
145
|
### See every outcome
|
|
105
146
|
|
|
106
|
-
Ask for each case by adding `sandbox_case` to the inputs, with a new `request_id` each time. For example: "Now try the
|
|
147
|
+
Ask for each case by adding `sandbox_case` to the inputs, with a new `request_id` each time. For example: "Now try the duplicate_record case with request id demo-0002."
|
|
107
148
|
|
|
108
149
|
| `sandbox_case` | `outcome` | What MockMed does |
|
|
109
150
|
| --- | --- | --- |
|
|
110
151
|
| `normal` (default) | `done` | Saves the note, and the record check finds it. |
|
|
111
152
|
| `duplicate_record` | `needs_review` | Lists the same referral twice, so OpenAdapt can't tell which record to open. It stops before saving. |
|
|
112
|
-
| `false_saved_banner` | `not_sure_if_saved` |
|
|
153
|
+
| `false_saved_banner` | `not_sure_if_saved` | Rejects the note on save, so it isn't stored. |
|
|
113
154
|
| `timeout_after_save` | `not_sure_if_saved` | Saves the note, then times out with an error. |
|
|
114
155
|
| `app_offline` | `did_not_run` | Doesn't answer, so nothing starts. |
|
|
115
156
|
|
|
@@ -117,11 +158,11 @@ The sandbox remembers each `request_id` across sessions. Sending a used `request
|
|
|
117
158
|
|
|
118
159
|
### Drive MockMed with the real engine
|
|
119
160
|
|
|
120
|
-
The `tutorial` extra makes openadapt-flow (Flow), the engine behind OpenAdapt, drive MockMed in a hidden browser. Replace the sandbox server with this one
|
|
161
|
+
The `tutorial` extra makes openadapt-flow (Flow), the engine behind OpenAdapt, drive MockMed in a hidden browser. Replace the sandbox server with this one, then restart `claude`:
|
|
121
162
|
|
|
122
163
|
```bash
|
|
123
164
|
claude mcp remove openadapt
|
|
124
|
-
claude mcp add openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]
|
|
165
|
+
claude mcp add --scope user openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve
|
|
125
166
|
```
|
|
126
167
|
|
|
127
168
|
When the server starts, Flow records the workflow once and, if needed, downloads a browser (about 300 MB). The first request waits for that. In our test on a Mac, the first request took about 80 seconds. The call returned `running` after 60 seconds, and the agent called `get_run` for the result. If setup takes more than 15 minutes, the request ends `did_not_run`. With Flow, a `done` result has `proof: "local"` instead of `"simulated"`.
|
|
@@ -157,7 +198,7 @@ The check that stops a second entry covers one runs folder. See `--runs-dir` und
|
|
|
157
198
|
### Read the other fields
|
|
158
199
|
|
|
159
200
|
- `label`: a short status you can display, such as "Done and checked".
|
|
160
|
-
- `reason`: a code from a fixed list that names the cause, such as `invalid_input` or `request_id_conflict`. Every code is in `REASONS` in [contract.py](
|
|
201
|
+
- `reason`: a code from a fixed list that names the cause, such as `invalid_input` or `request_id_conflict`. Every code is in `REASONS` in [contract.py](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/openadapt_flow/agent/contract.py), and [docs/DESIGN.md](docs/DESIGN.md#the-result-contract) explains how each one is chosen.
|
|
161
202
|
- `what_happened` and `next_action`: fixed sentences you can show a person. They never contain input values or screen text.
|
|
162
203
|
- `proof`: `local` for a `done` that was checked on your customer's computer, `simulated` for a sandbox run that didn't open the app, and `none` for every other outcome.
|
|
163
204
|
- `model_calls`: on runs that reached Flow, how many AI model calls the run made. It's 0 unless model grounding, a fallback that asks an AI model where to click, is turned on (see [Security](#security)).
|
|
@@ -180,7 +221,7 @@ The sandbox has all three tools. With your own workflows, `run_workflow` appears
|
|
|
180
221
|
|
|
181
222
|
## Developer setup
|
|
182
223
|
|
|
183
|
-
The package is a local Model Context Protocol (MCP) server that talks over stdio, plus an `openadapt-agent` command. It needs Python 3.10 to 3.12. It checks inputs, stops second entries, and turns Flow's report into one of the four outcomes. [openadapt-flow](https://github.com/OpenAdaptAI/
|
|
224
|
+
The package is a local Model Context Protocol (MCP) server that talks over stdio, plus an `openadapt-agent` command. It needs Python 3.10 to 3.12. It checks inputs, stops second entries, and turns Flow's report into one of the four outcomes. [openadapt-flow](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/flow) records, replays, and checks the workflows.
|
|
184
225
|
|
|
185
226
|
To see Flow on its own, install the OpenAdapt launcher with `pip install openadapt`, then run `openadapt flow tutorial` or `openadapt quickstart --break-it`.
|
|
186
227
|
|
|
@@ -193,7 +234,7 @@ Any MCP client can start the server with the command `uvx`. In a client that rea
|
|
|
193
234
|
"mcpServers": {
|
|
194
235
|
"openadapt": {
|
|
195
236
|
"command": "uvx",
|
|
196
|
-
"args": ["--python", "3.12", "
|
|
237
|
+
"args": ["--python", "3.12", "openadapt-agent", "serve"]
|
|
197
238
|
}
|
|
198
239
|
}
|
|
199
240
|
}
|
|
@@ -210,8 +251,7 @@ from mcp.client.stdio import stdio_client
|
|
|
210
251
|
|
|
211
252
|
SERVER = StdioServerParameters(
|
|
212
253
|
command="uvx",
|
|
213
|
-
args=["--python", "3.12", "
|
|
214
|
-
"openadapt-agent", "serve"],
|
|
254
|
+
args=["--python", "3.12", "openadapt-agent", "serve"],
|
|
215
255
|
)
|
|
216
256
|
|
|
217
257
|
|
|
@@ -236,7 +276,7 @@ The SDK starts the server with only a few environment variables. To pass others,
|
|
|
236
276
|
[scripts/smoke_client.py](scripts/smoke_client.py) is a fuller example that runs every sandbox case. From a clone of this repository, run `pip install -e .`, then:
|
|
237
277
|
|
|
238
278
|
```bash
|
|
239
|
-
python scripts/smoke_client.py -- uvx --python 3.12
|
|
279
|
+
python scripts/smoke_client.py -- uvx --python 3.12 openadapt-agent serve
|
|
240
280
|
```
|
|
241
281
|
|
|
242
282
|
If your agent runs in your own cloud, it can't reach this server, which has no network listener. The program that starts the server has to run on your customer's computer. One way to do that is a small worker there: it takes requests from your service over a connection it opens, starts this server, calls `run_workflow`, and sends each result back. The worker acts as your agent, so protect its connection like any other route to patient data. For a hosted route instead, [talk to us](https://openadapt.ai/qualify?why=embed).
|
|
@@ -254,7 +294,7 @@ A bundle is a compiled workflow folder that contains `workflow.json`, or `workfl
|
|
|
254
294
|
|
|
255
295
|
`openadapt-agent serve --allow-run` is the older form of `--mode production`, or of the sandbox when there's no `--bundles`.
|
|
256
296
|
|
|
257
|
-
Each run goes through `openadapt-flow run`. Flow drives web apps in Chromium, with the address set by `--url`. It also drives desktop apps and RDP and Citrix sessions, which can need Flow's own target flags passed with `--extra-run-arg`. The [openadapt-flow README](https://github.com/OpenAdaptAI/
|
|
297
|
+
Each run goes through `openadapt-flow run`. Flow drives web apps in Chromium, with the address set by `--url`. It also drives desktop apps and RDP and Citrix sessions, which can need Flow's own target flags passed with `--extra-run-arg`. The [openadapt-flow README](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/flow) covers each kind of app.
|
|
258
298
|
|
|
259
299
|
### Get a workflow ready to run
|
|
260
300
|
|
|
@@ -266,7 +306,7 @@ What Flow requires depends on the profile set in the deployment config (`--confi
|
|
|
266
306
|
- `standard` or `regulated`: certification, an active admission (a signed readiness test) for that exact bundle version, and a record check that reads the saved record through a separate path, such as the app's API, its database, or a second session. Under `standard`, a Citrix session with no separate way to read the record can't end `done`.
|
|
267
307
|
- `demo`: no certification, but Flow doesn't confirm the save, so a finished run ends `not_sure_if_saved`.
|
|
268
308
|
|
|
269
|
-
Flow's [execution profiles](https://github.com/OpenAdaptAI/
|
|
309
|
+
Flow's [execution profiles](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/EXECUTION_PROFILES.md) page explains each profile.
|
|
270
310
|
|
|
271
311
|
### Set server options
|
|
272
312
|
|
|
@@ -274,10 +314,11 @@ Flow's [execution profiles](https://github.com/OpenAdaptAI/openadapt-flow/blob/m
|
|
|
274
314
|
| --- | --- |
|
|
275
315
|
| `--runs-dir DIR` | Where run records and Flow's evidence go. The default is `~/.openadapt/runs` (or `OPENADAPT_AGENT_RUNS_DIR` when it's set), never the folder where the client starts the server; the sandbox uses `~/.openadapt/agent-sandbox`. The server prints the folder it uses when it starts. The check that stops a second entry covers one runs folder, so give every server for the same work the same folder. Earlier versions used `./runs`; if that folder holds their records and you don't pass `--runs-dir`, the server won't start, so you choose which folder to keep. |
|
|
276
316
|
| `--url URL` | The app's address, passed to every Flow run. |
|
|
277
|
-
| `--config YAML` | Flow's deployment config ([example](https://github.com/OpenAdaptAI/
|
|
317
|
+
| `--config YAML` | Flow's deployment config ([example](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/deployment.example.yaml)), which sets the profile and whether model grounding is allowed. |
|
|
278
318
|
| `--policy NAME-OR-PATH` | The policy Flow certifies against, such as `clinical-write` or `permissive`. |
|
|
279
319
|
| `--timeout SECONDS` | How long one run may work (default 600). Time a person spends approving a save doesn't count. A run stopped at the limit is `not_sure_if_saved`. |
|
|
280
|
-
| `--approval-mode MODE` | Whether
|
|
320
|
+
| `--approval-mode MODE` | Whether each save waits for approval. Without it, Flow decides: under `standard` and `regulated` a run stops before each save until it's approved (`each_item`). `not_gated` turns that off for every run this server starts; each result records it under `technical.approval_mode`. |
|
|
321
|
+
| `--delegate-approvals AGENT_ID` | Lets your agent answer a waiting save as `AGENT_ID` (an opaque id such as `agent:intake-bot`), with `list_approval_requests` and `answer_approval_request`. Flow accepts the answer only where the run's approver policy allows an agent for that step, and records the agent as the approver. By default only a person may answer. Needs an openadapt-flow with delegated approvers (not released yet). |
|
|
281
322
|
| `--headed` | Shows the browser. A person needs it to continue or skip a stopped run in a web app. |
|
|
282
323
|
| `--extra-run-arg ARG`, `--flow-cli CMD` | Change how Flow is called. Either one can relax Flow's checks, for example `--extra-run-arg=--allow-unencrypted`. |
|
|
283
324
|
| `--allow-protected-export`, `--allow-synthetic-recorded-defaults`, `--allow-model-grounding` | Off by default. See [Security](#security). |
|
|
@@ -292,7 +333,7 @@ Under `standard` and `regulated`, Flow stops before each save and waits for a pe
|
|
|
292
333
|
|
|
293
334
|
With `--bundles`, the server also registers read-only tools for workflows and runs: `get_workflow`, `get_run_report`, `list_needs_attention`, and `get_attention_item`. With `--mode production` or `--mode attended`, it also registers a deprecated `run_workflow_<id>` for each workflow. Those tools take no `request_id`, so a retry can enter the values twice. Use `run_workflow` instead.
|
|
294
335
|
|
|
295
|
-
`list_workflows`, `run_workflow`, and `get_run` return `structuredContent` that matches their `outputSchema`, defined in [contract.py](
|
|
336
|
+
`list_workflows`, `run_workflow`, and `get_run` return `structuredContent` that matches their `outputSchema`, defined in [contract.py](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/openadapt_flow/agent/contract.py), plus the same JSON as text.
|
|
296
337
|
|
|
297
338
|
### Decide stopped runs
|
|
298
339
|
|
|
@@ -337,26 +378,40 @@ If a workflow's name would come out as either one, emit-skill names the skill `o
|
|
|
337
378
|
|
|
338
379
|
### Record a first workflow
|
|
339
380
|
|
|
340
|
-
`serve --authoring` adds recording tools, such as `observe`, `start_record`, `click`, `pause_for_input`, `stop_record`, `compile`, and `admit`. [docs/DESIGN.md](docs/DESIGN.md#recording-tools) lists all 14.
|
|
381
|
+
`serve --authoring` adds recording tools, such as `observe`, `start_record`, `click`, `pause_for_input`, `stop_record`, `compile`, and `admit`. [docs/DESIGN.md](docs/DESIGN.md#recording-tools) lists all 14. A person or your agent shows the task with them, in a web app, a native Windows app, or an RDP or Citrix session, and a person stays at the computer to sign in and accept the result. A task can be learned from one or more demonstrations. The recording server doesn't turn on runs.
|
|
341
382
|
|
|
342
|
-
1.
|
|
383
|
+
1. Register a recording server. The `tutorial` extra brings the browser driver that `--url` needs. `--url` opens the app in a new Chromium window with no saved sign-ins, and `--headed`, which `--url` requires, keeps that window visible so the person can sign in.
|
|
343
384
|
|
|
344
385
|
```bash
|
|
345
|
-
claude mcp add openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial]
|
|
386
|
+
claude mcp add --scope user openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve --authoring --url https://app.example.com --headed
|
|
346
387
|
```
|
|
347
388
|
|
|
348
|
-
|
|
389
|
+
This only registers the server. Claude Code starts it the next time you run `claude`.
|
|
390
|
+
|
|
391
|
+
2. Run `claude` and ask your agent to record the task with the person. When the agent pauses for sign-in, the person signs in to the app in that window.
|
|
349
392
|
3. When the task is done, the agent calls `compile`. It writes the bundle to `<runs-dir>/authoring/bundle`, which is `~/.openadapt/runs/authoring/bundle` by default.
|
|
350
393
|
4. The agent calls `admit`. Your MCP client then shows the person a confirmation form, and only the person's answer there accepts the bundle. If the client can't show forms (MCP form elicitation), `admit` refuses and nothing is accepted.
|
|
351
394
|
5. Get the bundle ready to run (see [Get a workflow ready to run](#get-a-workflow-ready-to-run)). Then serve it with `--mode production --bundles <runs-dir>/authoring/bundle`.
|
|
352
395
|
|
|
353
|
-
Use `--url URL --headed` on every platform. Without `--url`, the server exits on Linux, and on macOS it uses whatever window is in front when the client starts the server, or exits.
|
|
396
|
+
Use `--url URL --headed` for a web app on every platform. Without `--url`, the server exits on Linux, and on macOS it uses whatever window is in front when the client starts the server, or exits.
|
|
354
397
|
|
|
355
|
-
|
|
398
|
+
For a native Windows app, start Flow's Windows agent server in the signed-in desktop session on the Windows computer (`python -m openadapt_flow.backends.win_agent.server --port 5001`) and pass `--windows-agent-url http://localhost:5001`. The agent can run on that computer or on another one, such as a Mac. The server listens only on the Windows computer by default, so from another computer forward the port over SSH or serve it over HTTPS. Your agent's clicks and keys go through the same synthetic-input path that replay uses, and the recording keeps each clicked control's UI Automation id when Windows reports one. Set `OAFLOW_AGENT_TOKEN` to the same value for the server and the agent.
|
|
356
399
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
400
|
+
For an RDP or Citrix session, pass `--remote-window APP` (the client app, for example `"Microsoft Remote Desktop"`) or `--citrix`, and `--remote-window-title` when the app has more than one window. A remote session is screen-only: there's no DOM or UI Automation tree, so `observe` returns no nodes and your agent clicks x,y pixels in the client window and presses keys, the way a person would. To let your agent see that window, add `--authoring-screens scrubbed`, which turns on a `screen` tool that returns the frame with identifiers scrubbed and shares nothing if scrubbing fails. `--authoring-screens unscrubbed` skips scrubbing. Screens are off by default.
|
|
401
|
+
|
|
402
|
+
[Recording on Windows, RDP and Citrix](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/RECORDING_ON_WINDOWS_RDP_CITRIX.md) explains the Windows agent server, why it's needed when the agent runs on another computer, how to start it, the token, and the RDP and Citrix pixel path.
|
|
403
|
+
|
|
404
|
+
The recording marks every step as the agent's or the person's (`actor` in `events.jsonl`, `demonstrated_by` in `meta.json`), and a person still accepts the result. On Windows with none of these flags, the tools can only tell the person what to click.
|
|
405
|
+
|
|
406
|
+
ChatGPT and Claude in a web browser can't start a server on your computer. To record from one of them:
|
|
407
|
+
|
|
408
|
+
1. On https://openadapt.ai/#job-box, type the job under **What job do you want to automate?** and click **Get a job page**.
|
|
409
|
+
2. On the job page, click **Connect this computer**. Its **Open OpenAdapt** link is the runner link (`openadapt://runner?pack=...&bind=oab_...`). It opens OpenAdapt Desktop if you have it. The link works once and expires after five minutes if nobody claims it.
|
|
410
|
+
3. Without Desktop, copy that link and run this on the computer that has the app:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
openadapt-agent authoring connect '<runner link>'
|
|
414
|
+
```
|
|
360
415
|
|
|
361
416
|
It claims the job, polls openadapt.ai over outgoing HTTPS, and asks you in the terminal before a chat account may drive it. Don't confuse it with the launcher's `openadapt connect`, which pairs a computer with OpenAdapt Cloud. [docs/MAILBOX_CLI.md](docs/MAILBOX_CLI.md) has the details.
|
|
362
417
|
|
|
@@ -402,7 +457,7 @@ openadapt-agent seal verify https://example.com/receipt.json --json
|
|
|
402
457
|
- The check that stops a second entry covers one runs folder. Pass the same absolute `--runs-dir` every time.
|
|
403
458
|
- If the server exits during a run, the run reads as `not_sure_if_saved`, and Flow may still finish it.
|
|
404
459
|
- This server issues no signed receipts itself. `proof` is `sealed` only when a run is connected to OpenAdapt Cloud Execute, Cloud signed its receipt, and that signature verifies against keys you pinned (see [Seals](#seals)).
|
|
405
|
-
- With openadapt-flow 2,
|
|
460
|
+
- With openadapt-flow 2, each save waits for approval unless the operator names another mode (`serve --approval-mode problems_only` or `not_gated`). Your agent gets `needs_review` with the reason `waiting_for_approval`. A person answers on the computer that runs OpenAdapt, or your agent does when the server runs with `--delegate-approvals` and the run's approver policy allows an agent for that step. Nothing is saved without that answer. `get_approval_mode` tells your agent which mode applies; no tool changes it.
|
|
406
461
|
- Each call carries one request. There's no batch call.
|
|
407
462
|
- Accounts, separation between customers, fleet policy, and hosted runs belong to OpenAdapt Cloud.
|
|
408
463
|
|
|
@@ -414,7 +469,7 @@ Under Flow's `standard` and `regulated` profiles, each workflow version also nee
|
|
|
414
469
|
|
|
415
470
|
## Package history
|
|
416
471
|
|
|
417
|
-
Before version 2, this package ran AI agents that drove the screen. The name now refers to the agents that call it. A customer's workflows are supplied with `--bundles` and never ship in this package or its registry listing, and an install from a registry starts read-only. The MCP registry reads [server.json](server.json), Smithery packs from [manifest.json](manifest.json), and [llms.txt](llms.txt) describes the package for AI assistants. See [docs/DISTRIBUTION.md](docs/DISTRIBUTION.md).
|
|
472
|
+
Before version 2, this package ran AI agents that drove the screen. The name now refers to the agents that call it. A customer's workflows are supplied with `--bundles` and never ship in this package or its registry listing, and an install from a registry starts read-only. The MCP registry reads [server.json](server.json), Smithery packs from [manifest.json](manifest.json), and [llms.txt](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/llms.txt) describes the package for AI assistants. See [docs/DISTRIBUTION.md](docs/DISTRIBUTION.md).
|
|
418
473
|
|
|
419
474
|
<!-- mcp-name: io.github.OpenAdaptAI/openadapt-agent -->
|
|
420
475
|
|
|
@@ -1,44 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: openadapt-agent
|
|
3
|
-
Version: 2.2.0
|
|
4
|
-
Summary: Let your AI agent enter information in apps with no API and get back whether it saved (MCP and Agent Skills)
|
|
5
|
-
Project-URL: Homepage, https://github.com/OpenAdaptAI/openadapt-agent
|
|
6
|
-
Project-URL: Repository, https://github.com/OpenAdaptAI/openadapt-agent
|
|
7
|
-
Project-URL: Documentation, https://github.com/OpenAdaptAI/openadapt-agent#readme
|
|
8
|
-
Project-URL: Bug Tracker, https://github.com/OpenAdaptAI/openadapt-agent/issues
|
|
9
|
-
Author-email: Richard Abrich <richard@openadapt.ai>
|
|
10
|
-
Maintainer-email: OpenAdaptAI <contact@openadapt.ai>
|
|
11
|
-
License-Expression: MIT
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Keywords: agent-skills,ai-agents,automation,ehr,gui,mcp,openadapt,rpa,workflow
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
-
Requires-Python: <3.13,>=3.10
|
|
23
|
-
Requires-Dist: anyio>=4.0
|
|
24
|
-
Requires-Dist: cryptography>=50.0.0
|
|
25
|
-
Requires-Dist: jsonschema>=4.20.0
|
|
26
|
-
Requires-Dist: mcp<3,>=1.28
|
|
27
|
-
Requires-Dist: openadapt-flow<3,>=2.1.0
|
|
28
|
-
Provides-Extra: dev
|
|
29
|
-
Requires-Dist: build>=1.2.0; extra == 'dev'
|
|
30
|
-
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
31
|
-
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
32
|
-
Provides-Extra: repair-screens
|
|
33
|
-
Requires-Dist: openadapt-privacy[presidio]>=1.1.2; extra == 'repair-screens'
|
|
34
|
-
Provides-Extra: tutorial
|
|
35
|
-
Requires-Dist: openadapt-flow[browser,macos]<3,>=2.1.0; extra == 'tutorial'
|
|
36
|
-
Description-Content-Type: text/markdown
|
|
37
|
-
|
|
38
1
|
# OpenAdapt Agent
|
|
39
2
|
|
|
40
|
-
[](https://github.com/OpenAdaptAI/OpenAdapt/actions/workflows/packages.yml)
|
|
4
|
+
[](https://pypi.org/project/openadapt-agent/)
|
|
5
|
+
[](https://pypi.org/project/openadapt-agent/)
|
|
6
|
+
[](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/agent/LICENSE)
|
|
42
7
|
|
|
43
8
|
Your AI agent decides what to enter. OpenAdapt enters it in the app and checks that it saved.
|
|
44
9
|
|
|
@@ -90,28 +55,30 @@ flowchart LR
|
|
|
90
55
|
|
|
91
56
|
| You build | OpenAdapt provides |
|
|
92
57
|
| --- | --- |
|
|
93
|
-
| The agent that reads documents and decides what to enter | A workflow
|
|
58
|
+
| The agent that reads documents and decides what to enter | A workflow learned from one or more demonstrations in the real app, where a person or an agent shows the task |
|
|
94
59
|
| The call to `run_workflow`, with your own `request_id` | The run on your customer's computer, with a right-record check before it types and a record check after it saves |
|
|
95
60
|
| What your product does with each outcome | One result per request, and no second entry when your agent repeats a `request_id` |
|
|
96
61
|
| Your tests against the four outcomes | A sandbox that returns each outcome on demand |
|
|
97
62
|
|
|
98
|
-
Your customer provides the computer and a person for runs that stop.
|
|
63
|
+
Your customer provides the computer and a person for runs that stop. A person or an agent shows the task, in web apps, native Windows apps, and over Citrix or remote desktop. A person accepts the result before it runs. See [Record a first workflow](#record-a-first-workflow), or [talk to us](https://openadapt.ai/qualify?why=embed) about setting it up.
|
|
99
64
|
|
|
100
65
|
## Try it in three steps
|
|
101
66
|
|
|
102
67
|
The sandbox is a practice server that needs no account. It has one workflow, `add_triage_note`, which adds a note to the first referral in MockMed, a test clinic app with made-up patients.
|
|
103
68
|
|
|
104
|
-
You need [Claude Code](https://claude.com/claude-code) (signed in)
|
|
69
|
+
You need [Claude Code](https://claude.com/claude-code) (signed in) and [uv](https://docs.astral.sh/uv/). To use a different client or your own code, see [Connect your own agent](#connect-your-own-agent).
|
|
105
70
|
|
|
106
|
-
1.
|
|
71
|
+
1. Register the sandbox server. `--scope user` makes it available in every folder; without it, Claude Code saves it for the current folder only.
|
|
107
72
|
|
|
108
73
|
```bash
|
|
109
|
-
claude mcp add openadapt -- uvx --python 3.12
|
|
74
|
+
claude mcp add --scope user openadapt -- uvx --python 3.12 openadapt-agent serve
|
|
110
75
|
```
|
|
111
76
|
|
|
112
|
-
|
|
77
|
+
This only registers the server. It prints one line saying the server was added to user config, and nothing else.
|
|
78
|
+
|
|
79
|
+
2. Start Claude Code with `claude`. Claude Code starts the server. Optional: type `/mcp` to check that `openadapt` is connected.
|
|
113
80
|
|
|
114
|
-
3. Ask: "Use OpenAdapt to
|
|
81
|
+
3. Ask: "Use the OpenAdapt sandbox to run add_triage_note with the note 'Synthetic: recheck blood pressure in 2 weeks' and request id demo-0001."
|
|
115
82
|
|
|
116
83
|
Your agent should call `list_workflows`, then `run_workflow` with these arguments:
|
|
117
84
|
|
|
@@ -136,17 +103,17 @@ The result looks like this (some fields left out):
|
|
|
136
103
|
|
|
137
104
|
This install simulates each run without opening MockMed, and every result says so. To watch the real engine do the work, see [Drive MockMed with the real engine](#drive-mockmed-with-the-real-engine).
|
|
138
105
|
|
|
139
|
-
|
|
106
|
+
openadapt-agent installs from PyPI and requires openadapt-flow 2.1.0 or later, which is on PyPI and installs with it. To try unreleased changes, use `--from git+https://github.com/OpenAdaptAI/OpenAdapt#subdirectory=packages/agent` in place of the package name.
|
|
140
107
|
|
|
141
108
|
### See every outcome
|
|
142
109
|
|
|
143
|
-
Ask for each case by adding `sandbox_case` to the inputs, with a new `request_id` each time. For example: "Now try the
|
|
110
|
+
Ask for each case by adding `sandbox_case` to the inputs, with a new `request_id` each time. For example: "Now try the duplicate_record case with request id demo-0002."
|
|
144
111
|
|
|
145
112
|
| `sandbox_case` | `outcome` | What MockMed does |
|
|
146
113
|
| --- | --- | --- |
|
|
147
114
|
| `normal` (default) | `done` | Saves the note, and the record check finds it. |
|
|
148
115
|
| `duplicate_record` | `needs_review` | Lists the same referral twice, so OpenAdapt can't tell which record to open. It stops before saving. |
|
|
149
|
-
| `false_saved_banner` | `not_sure_if_saved` |
|
|
116
|
+
| `false_saved_banner` | `not_sure_if_saved` | Rejects the note on save, so it isn't stored. |
|
|
150
117
|
| `timeout_after_save` | `not_sure_if_saved` | Saves the note, then times out with an error. |
|
|
151
118
|
| `app_offline` | `did_not_run` | Doesn't answer, so nothing starts. |
|
|
152
119
|
|
|
@@ -154,11 +121,11 @@ The sandbox remembers each `request_id` across sessions. Sending a used `request
|
|
|
154
121
|
|
|
155
122
|
### Drive MockMed with the real engine
|
|
156
123
|
|
|
157
|
-
The `tutorial` extra makes openadapt-flow (Flow), the engine behind OpenAdapt, drive MockMed in a hidden browser. Replace the sandbox server with this one
|
|
124
|
+
The `tutorial` extra makes openadapt-flow (Flow), the engine behind OpenAdapt, drive MockMed in a hidden browser. Replace the sandbox server with this one, then restart `claude`:
|
|
158
125
|
|
|
159
126
|
```bash
|
|
160
127
|
claude mcp remove openadapt
|
|
161
|
-
claude mcp add openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]
|
|
128
|
+
claude mcp add --scope user openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve
|
|
162
129
|
```
|
|
163
130
|
|
|
164
131
|
When the server starts, Flow records the workflow once and, if needed, downloads a browser (about 300 MB). The first request waits for that. In our test on a Mac, the first request took about 80 seconds. The call returned `running` after 60 seconds, and the agent called `get_run` for the result. If setup takes more than 15 minutes, the request ends `did_not_run`. With Flow, a `done` result has `proof: "local"` instead of `"simulated"`.
|
|
@@ -194,7 +161,7 @@ The check that stops a second entry covers one runs folder. See `--runs-dir` und
|
|
|
194
161
|
### Read the other fields
|
|
195
162
|
|
|
196
163
|
- `label`: a short status you can display, such as "Done and checked".
|
|
197
|
-
- `reason`: a code from a fixed list that names the cause, such as `invalid_input` or `request_id_conflict`. Every code is in `REASONS` in [contract.py](
|
|
164
|
+
- `reason`: a code from a fixed list that names the cause, such as `invalid_input` or `request_id_conflict`. Every code is in `REASONS` in [contract.py](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/openadapt_flow/agent/contract.py), and [docs/DESIGN.md](docs/DESIGN.md#the-result-contract) explains how each one is chosen.
|
|
198
165
|
- `what_happened` and `next_action`: fixed sentences you can show a person. They never contain input values or screen text.
|
|
199
166
|
- `proof`: `local` for a `done` that was checked on your customer's computer, `simulated` for a sandbox run that didn't open the app, and `none` for every other outcome.
|
|
200
167
|
- `model_calls`: on runs that reached Flow, how many AI model calls the run made. It's 0 unless model grounding, a fallback that asks an AI model where to click, is turned on (see [Security](#security)).
|
|
@@ -217,7 +184,7 @@ The sandbox has all three tools. With your own workflows, `run_workflow` appears
|
|
|
217
184
|
|
|
218
185
|
## Developer setup
|
|
219
186
|
|
|
220
|
-
The package is a local Model Context Protocol (MCP) server that talks over stdio, plus an `openadapt-agent` command. It needs Python 3.10 to 3.12. It checks inputs, stops second entries, and turns Flow's report into one of the four outcomes. [openadapt-flow](https://github.com/OpenAdaptAI/
|
|
187
|
+
The package is a local Model Context Protocol (MCP) server that talks over stdio, plus an `openadapt-agent` command. It needs Python 3.10 to 3.12. It checks inputs, stops second entries, and turns Flow's report into one of the four outcomes. [openadapt-flow](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/flow) records, replays, and checks the workflows.
|
|
221
188
|
|
|
222
189
|
To see Flow on its own, install the OpenAdapt launcher with `pip install openadapt`, then run `openadapt flow tutorial` or `openadapt quickstart --break-it`.
|
|
223
190
|
|
|
@@ -230,7 +197,7 @@ Any MCP client can start the server with the command `uvx`. In a client that rea
|
|
|
230
197
|
"mcpServers": {
|
|
231
198
|
"openadapt": {
|
|
232
199
|
"command": "uvx",
|
|
233
|
-
"args": ["--python", "3.12", "
|
|
200
|
+
"args": ["--python", "3.12", "openadapt-agent", "serve"]
|
|
234
201
|
}
|
|
235
202
|
}
|
|
236
203
|
}
|
|
@@ -247,8 +214,7 @@ from mcp.client.stdio import stdio_client
|
|
|
247
214
|
|
|
248
215
|
SERVER = StdioServerParameters(
|
|
249
216
|
command="uvx",
|
|
250
|
-
args=["--python", "3.12", "
|
|
251
|
-
"openadapt-agent", "serve"],
|
|
217
|
+
args=["--python", "3.12", "openadapt-agent", "serve"],
|
|
252
218
|
)
|
|
253
219
|
|
|
254
220
|
|
|
@@ -273,7 +239,7 @@ The SDK starts the server with only a few environment variables. To pass others,
|
|
|
273
239
|
[scripts/smoke_client.py](scripts/smoke_client.py) is a fuller example that runs every sandbox case. From a clone of this repository, run `pip install -e .`, then:
|
|
274
240
|
|
|
275
241
|
```bash
|
|
276
|
-
python scripts/smoke_client.py -- uvx --python 3.12
|
|
242
|
+
python scripts/smoke_client.py -- uvx --python 3.12 openadapt-agent serve
|
|
277
243
|
```
|
|
278
244
|
|
|
279
245
|
If your agent runs in your own cloud, it can't reach this server, which has no network listener. The program that starts the server has to run on your customer's computer. One way to do that is a small worker there: it takes requests from your service over a connection it opens, starts this server, calls `run_workflow`, and sends each result back. The worker acts as your agent, so protect its connection like any other route to patient data. For a hosted route instead, [talk to us](https://openadapt.ai/qualify?why=embed).
|
|
@@ -291,7 +257,7 @@ A bundle is a compiled workflow folder that contains `workflow.json`, or `workfl
|
|
|
291
257
|
|
|
292
258
|
`openadapt-agent serve --allow-run` is the older form of `--mode production`, or of the sandbox when there's no `--bundles`.
|
|
293
259
|
|
|
294
|
-
Each run goes through `openadapt-flow run`. Flow drives web apps in Chromium, with the address set by `--url`. It also drives desktop apps and RDP and Citrix sessions, which can need Flow's own target flags passed with `--extra-run-arg`. The [openadapt-flow README](https://github.com/OpenAdaptAI/
|
|
260
|
+
Each run goes through `openadapt-flow run`. Flow drives web apps in Chromium, with the address set by `--url`. It also drives desktop apps and RDP and Citrix sessions, which can need Flow's own target flags passed with `--extra-run-arg`. The [openadapt-flow README](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/flow) covers each kind of app.
|
|
295
261
|
|
|
296
262
|
### Get a workflow ready to run
|
|
297
263
|
|
|
@@ -303,7 +269,7 @@ What Flow requires depends on the profile set in the deployment config (`--confi
|
|
|
303
269
|
- `standard` or `regulated`: certification, an active admission (a signed readiness test) for that exact bundle version, and a record check that reads the saved record through a separate path, such as the app's API, its database, or a second session. Under `standard`, a Citrix session with no separate way to read the record can't end `done`.
|
|
304
270
|
- `demo`: no certification, but Flow doesn't confirm the save, so a finished run ends `not_sure_if_saved`.
|
|
305
271
|
|
|
306
|
-
Flow's [execution profiles](https://github.com/OpenAdaptAI/
|
|
272
|
+
Flow's [execution profiles](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/EXECUTION_PROFILES.md) page explains each profile.
|
|
307
273
|
|
|
308
274
|
### Set server options
|
|
309
275
|
|
|
@@ -311,10 +277,11 @@ Flow's [execution profiles](https://github.com/OpenAdaptAI/openadapt-flow/blob/m
|
|
|
311
277
|
| --- | --- |
|
|
312
278
|
| `--runs-dir DIR` | Where run records and Flow's evidence go. The default is `~/.openadapt/runs` (or `OPENADAPT_AGENT_RUNS_DIR` when it's set), never the folder where the client starts the server; the sandbox uses `~/.openadapt/agent-sandbox`. The server prints the folder it uses when it starts. The check that stops a second entry covers one runs folder, so give every server for the same work the same folder. Earlier versions used `./runs`; if that folder holds their records and you don't pass `--runs-dir`, the server won't start, so you choose which folder to keep. |
|
|
313
279
|
| `--url URL` | The app's address, passed to every Flow run. |
|
|
314
|
-
| `--config YAML` | Flow's deployment config ([example](https://github.com/OpenAdaptAI/
|
|
280
|
+
| `--config YAML` | Flow's deployment config ([example](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/deployment.example.yaml)), which sets the profile and whether model grounding is allowed. |
|
|
315
281
|
| `--policy NAME-OR-PATH` | The policy Flow certifies against, such as `clinical-write` or `permissive`. |
|
|
316
282
|
| `--timeout SECONDS` | How long one run may work (default 600). Time a person spends approving a save doesn't count. A run stopped at the limit is `not_sure_if_saved`. |
|
|
317
|
-
| `--approval-mode MODE` | Whether
|
|
283
|
+
| `--approval-mode MODE` | Whether each save waits for approval. Without it, Flow decides: under `standard` and `regulated` a run stops before each save until it's approved (`each_item`). `not_gated` turns that off for every run this server starts; each result records it under `technical.approval_mode`. |
|
|
284
|
+
| `--delegate-approvals AGENT_ID` | Lets your agent answer a waiting save as `AGENT_ID` (an opaque id such as `agent:intake-bot`), with `list_approval_requests` and `answer_approval_request`. Flow accepts the answer only where the run's approver policy allows an agent for that step, and records the agent as the approver. By default only a person may answer. Needs an openadapt-flow with delegated approvers (not released yet). |
|
|
318
285
|
| `--headed` | Shows the browser. A person needs it to continue or skip a stopped run in a web app. |
|
|
319
286
|
| `--extra-run-arg ARG`, `--flow-cli CMD` | Change how Flow is called. Either one can relax Flow's checks, for example `--extra-run-arg=--allow-unencrypted`. |
|
|
320
287
|
| `--allow-protected-export`, `--allow-synthetic-recorded-defaults`, `--allow-model-grounding` | Off by default. See [Security](#security). |
|
|
@@ -329,7 +296,7 @@ Under `standard` and `regulated`, Flow stops before each save and waits for a pe
|
|
|
329
296
|
|
|
330
297
|
With `--bundles`, the server also registers read-only tools for workflows and runs: `get_workflow`, `get_run_report`, `list_needs_attention`, and `get_attention_item`. With `--mode production` or `--mode attended`, it also registers a deprecated `run_workflow_<id>` for each workflow. Those tools take no `request_id`, so a retry can enter the values twice. Use `run_workflow` instead.
|
|
331
298
|
|
|
332
|
-
`list_workflows`, `run_workflow`, and `get_run` return `structuredContent` that matches their `outputSchema`, defined in [contract.py](
|
|
299
|
+
`list_workflows`, `run_workflow`, and `get_run` return `structuredContent` that matches their `outputSchema`, defined in [contract.py](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/openadapt_flow/agent/contract.py), plus the same JSON as text.
|
|
333
300
|
|
|
334
301
|
### Decide stopped runs
|
|
335
302
|
|
|
@@ -374,26 +341,40 @@ If a workflow's name would come out as either one, emit-skill names the skill `o
|
|
|
374
341
|
|
|
375
342
|
### Record a first workflow
|
|
376
343
|
|
|
377
|
-
`serve --authoring` adds recording tools, such as `observe`, `start_record`, `click`, `pause_for_input`, `stop_record`, `compile`, and `admit`. [docs/DESIGN.md](docs/DESIGN.md#recording-tools) lists all 14.
|
|
344
|
+
`serve --authoring` adds recording tools, such as `observe`, `start_record`, `click`, `pause_for_input`, `stop_record`, `compile`, and `admit`. [docs/DESIGN.md](docs/DESIGN.md#recording-tools) lists all 14. A person or your agent shows the task with them, in a web app, a native Windows app, or an RDP or Citrix session, and a person stays at the computer to sign in and accept the result. A task can be learned from one or more demonstrations. The recording server doesn't turn on runs.
|
|
378
345
|
|
|
379
|
-
1.
|
|
346
|
+
1. Register a recording server. The `tutorial` extra brings the browser driver that `--url` needs. `--url` opens the app in a new Chromium window with no saved sign-ins, and `--headed`, which `--url` requires, keeps that window visible so the person can sign in.
|
|
380
347
|
|
|
381
348
|
```bash
|
|
382
|
-
claude mcp add openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial]
|
|
349
|
+
claude mcp add --scope user openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve --authoring --url https://app.example.com --headed
|
|
383
350
|
```
|
|
384
351
|
|
|
385
|
-
|
|
352
|
+
This only registers the server. Claude Code starts it the next time you run `claude`.
|
|
353
|
+
|
|
354
|
+
2. Run `claude` and ask your agent to record the task with the person. When the agent pauses for sign-in, the person signs in to the app in that window.
|
|
386
355
|
3. When the task is done, the agent calls `compile`. It writes the bundle to `<runs-dir>/authoring/bundle`, which is `~/.openadapt/runs/authoring/bundle` by default.
|
|
387
356
|
4. The agent calls `admit`. Your MCP client then shows the person a confirmation form, and only the person's answer there accepts the bundle. If the client can't show forms (MCP form elicitation), `admit` refuses and nothing is accepted.
|
|
388
357
|
5. Get the bundle ready to run (see [Get a workflow ready to run](#get-a-workflow-ready-to-run)). Then serve it with `--mode production --bundles <runs-dir>/authoring/bundle`.
|
|
389
358
|
|
|
390
|
-
Use `--url URL --headed` on every platform. Without `--url`, the server exits on Linux, and on macOS it uses whatever window is in front when the client starts the server, or exits.
|
|
359
|
+
Use `--url URL --headed` for a web app on every platform. Without `--url`, the server exits on Linux, and on macOS it uses whatever window is in front when the client starts the server, or exits.
|
|
391
360
|
|
|
392
|
-
|
|
361
|
+
For a native Windows app, start Flow's Windows agent server in the signed-in desktop session on the Windows computer (`python -m openadapt_flow.backends.win_agent.server --port 5001`) and pass `--windows-agent-url http://localhost:5001`. The agent can run on that computer or on another one, such as a Mac. The server listens only on the Windows computer by default, so from another computer forward the port over SSH or serve it over HTTPS. Your agent's clicks and keys go through the same synthetic-input path that replay uses, and the recording keeps each clicked control's UI Automation id when Windows reports one. Set `OAFLOW_AGENT_TOKEN` to the same value for the server and the agent.
|
|
393
362
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
363
|
+
For an RDP or Citrix session, pass `--remote-window APP` (the client app, for example `"Microsoft Remote Desktop"`) or `--citrix`, and `--remote-window-title` when the app has more than one window. A remote session is screen-only: there's no DOM or UI Automation tree, so `observe` returns no nodes and your agent clicks x,y pixels in the client window and presses keys, the way a person would. To let your agent see that window, add `--authoring-screens scrubbed`, which turns on a `screen` tool that returns the frame with identifiers scrubbed and shares nothing if scrubbing fails. `--authoring-screens unscrubbed` skips scrubbing. Screens are off by default.
|
|
364
|
+
|
|
365
|
+
[Recording on Windows, RDP and Citrix](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/RECORDING_ON_WINDOWS_RDP_CITRIX.md) explains the Windows agent server, why it's needed when the agent runs on another computer, how to start it, the token, and the RDP and Citrix pixel path.
|
|
366
|
+
|
|
367
|
+
The recording marks every step as the agent's or the person's (`actor` in `events.jsonl`, `demonstrated_by` in `meta.json`), and a person still accepts the result. On Windows with none of these flags, the tools can only tell the person what to click.
|
|
368
|
+
|
|
369
|
+
ChatGPT and Claude in a web browser can't start a server on your computer. To record from one of them:
|
|
370
|
+
|
|
371
|
+
1. On https://openadapt.ai/#job-box, type the job under **What job do you want to automate?** and click **Get a job page**.
|
|
372
|
+
2. On the job page, click **Connect this computer**. Its **Open OpenAdapt** link is the runner link (`openadapt://runner?pack=...&bind=oab_...`). It opens OpenAdapt Desktop if you have it. The link works once and expires after five minutes if nobody claims it.
|
|
373
|
+
3. Without Desktop, copy that link and run this on the computer that has the app:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
openadapt-agent authoring connect '<runner link>'
|
|
377
|
+
```
|
|
397
378
|
|
|
398
379
|
It claims the job, polls openadapt.ai over outgoing HTTPS, and asks you in the terminal before a chat account may drive it. Don't confuse it with the launcher's `openadapt connect`, which pairs a computer with OpenAdapt Cloud. [docs/MAILBOX_CLI.md](docs/MAILBOX_CLI.md) has the details.
|
|
399
380
|
|
|
@@ -439,7 +420,7 @@ openadapt-agent seal verify https://example.com/receipt.json --json
|
|
|
439
420
|
- The check that stops a second entry covers one runs folder. Pass the same absolute `--runs-dir` every time.
|
|
440
421
|
- If the server exits during a run, the run reads as `not_sure_if_saved`, and Flow may still finish it.
|
|
441
422
|
- This server issues no signed receipts itself. `proof` is `sealed` only when a run is connected to OpenAdapt Cloud Execute, Cloud signed its receipt, and that signature verifies against keys you pinned (see [Seals](#seals)).
|
|
442
|
-
- With openadapt-flow 2,
|
|
423
|
+
- With openadapt-flow 2, each save waits for approval unless the operator names another mode (`serve --approval-mode problems_only` or `not_gated`). Your agent gets `needs_review` with the reason `waiting_for_approval`. A person answers on the computer that runs OpenAdapt, or your agent does when the server runs with `--delegate-approvals` and the run's approver policy allows an agent for that step. Nothing is saved without that answer. `get_approval_mode` tells your agent which mode applies; no tool changes it.
|
|
443
424
|
- Each call carries one request. There's no batch call.
|
|
444
425
|
- Accounts, separation between customers, fleet policy, and hosted runs belong to OpenAdapt Cloud.
|
|
445
426
|
|
|
@@ -451,7 +432,7 @@ Under Flow's `standard` and `regulated` profiles, each workflow version also nee
|
|
|
451
432
|
|
|
452
433
|
## Package history
|
|
453
434
|
|
|
454
|
-
Before version 2, this package ran AI agents that drove the screen. The name now refers to the agents that call it. A customer's workflows are supplied with `--bundles` and never ship in this package or its registry listing, and an install from a registry starts read-only. The MCP registry reads [server.json](server.json), Smithery packs from [manifest.json](manifest.json), and [llms.txt](llms.txt) describes the package for AI assistants. See [docs/DISTRIBUTION.md](docs/DISTRIBUTION.md).
|
|
435
|
+
Before version 2, this package ran AI agents that drove the screen. The name now refers to the agents that call it. A customer's workflows are supplied with `--bundles` and never ship in this package or its registry listing, and an install from a registry starts read-only. The MCP registry reads [server.json](server.json), Smithery packs from [manifest.json](manifest.json), and [llms.txt](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/llms.txt) describes the package for AI assistants. See [docs/DISTRIBUTION.md](docs/DISTRIBUTION.md).
|
|
455
436
|
|
|
456
437
|
<!-- mcp-name: io.github.OpenAdaptAI/openadapt-agent -->
|
|
457
438
|
|