openadapt-agent 2.1.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.
Files changed (94) hide show
  1. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/workflows/ci.yml +24 -2
  2. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/workflows/codeql.yml +2 -2
  3. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/workflows/release.yml +4 -4
  4. openadapt_agent-2.2.1/CHANGELOG.md +13 -0
  5. openadapt_agent-2.1.0/README.md → openadapt_agent-2.2.1/PKG-INFO +106 -39
  6. openadapt_agent-2.1.0/PKG-INFO → openadapt_agent-2.2.1/README.md +69 -74
  7. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/docs/DESIGN.md +20 -6
  8. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/docs/DISTRIBUTION.md +5 -5
  9. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/docs/MAILBOX_CLI.md +1 -1
  10. openadapt_agent-2.2.1/docs/REPAIR.md +95 -0
  11. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/docs/examples/sandbox-results.json +1 -1
  12. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/manifest.json +3 -3
  13. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/pyproject.toml +12 -7
  14. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/smoke_client.py +1 -2
  15. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/server.json +5 -4
  16. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/skills/openadapt-gui-write/SKILL.md +3 -5
  17. openadapt_agent-2.2.1/src/openadapt_agent/__init__.py +66 -0
  18. openadapt_agent-2.2.1/src/openadapt_agent/mcpb_entry.py +6 -0
  19. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_approval.py +44 -0
  20. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_authoring.py +48 -12
  21. openadapt_agent-2.2.1/tests/test_authoring_native.py +229 -0
  22. openadapt_agent-2.2.1/tests/test_delegated_approval.py +157 -0
  23. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_distribution.py +29 -11
  24. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_mailbox.py +4 -4
  25. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_mcpb_entry.py +1 -1
  26. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_public_lifecycle.py +1 -1
  27. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_readme_commands.py +1 -1
  28. openadapt_agent-2.2.1/tests/test_repair.py +398 -0
  29. openadapt_agent-2.2.1/tests/test_repair_branch.py +73 -0
  30. openadapt_agent-2.2.1/tests/test_repair_e2e.py +201 -0
  31. openadapt_agent-2.2.1/tests/test_repair_hold.py +107 -0
  32. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_sandbox.py +4 -4
  33. openadapt_agent-2.2.1/tests/test_shim.py +37 -0
  34. openadapt_agent-2.2.1/uv.lock +2643 -0
  35. openadapt_agent-2.1.0/llms.txt +0 -65
  36. openadapt_agent-2.1.0/src/openadapt_agent/__init__.py +0 -26
  37. openadapt_agent-2.1.0/src/openadapt_agent/__main__.py +0 -6
  38. openadapt_agent-2.1.0/src/openadapt_agent/approval.py +0 -124
  39. openadapt_agent-2.1.0/src/openadapt_agent/attended.py +0 -427
  40. openadapt_agent-2.1.0/src/openadapt_agent/authoring.py +0 -1689
  41. openadapt_agent-2.1.0/src/openadapt_agent/bridge.py +0 -771
  42. openadapt_agent-2.1.0/src/openadapt_agent/bundles.py +0 -245
  43. openadapt_agent-2.1.0/src/openadapt_agent/cards.py +0 -346
  44. openadapt_agent-2.1.0/src/openadapt_agent/cli.py +0 -625
  45. openadapt_agent-2.1.0/src/openadapt_agent/contract.py +0 -897
  46. openadapt_agent-2.1.0/src/openadapt_agent/copy.py +0 -53
  47. openadapt_agent-2.1.0/src/openadapt_agent/flow_service.py +0 -51
  48. openadapt_agent-2.1.0/src/openadapt_agent/mailbox.py +0 -806
  49. openadapt_agent-2.1.0/src/openadapt_agent/mcp.py +0 -411
  50. openadapt_agent-2.1.0/src/openadapt_agent/mcpb_entry.py +0 -66
  51. openadapt_agent-2.1.0/src/openadapt_agent/runner.py +0 -869
  52. openadapt_agent-2.1.0/src/openadapt_agent/runner_bind.py +0 -185
  53. openadapt_agent-2.1.0/src/openadapt_agent/runs.py +0 -381
  54. openadapt_agent-2.1.0/src/openadapt_agent/sandbox.py +0 -512
  55. openadapt_agent-2.1.0/src/openadapt_agent/seal.py +0 -210
  56. openadapt_agent-2.1.0/src/openadapt_agent/seal_cli.py +0 -276
  57. openadapt_agent-2.1.0/src/openadapt_agent/service.py +0 -500
  58. openadapt_agent-2.1.0/src/openadapt_agent/skill.py +0 -188
  59. openadapt_agent-2.1.0/src/openadapt_agent/tutorial.py +0 -169
  60. openadapt_agent-2.1.0/uv.lock +0 -1300
  61. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/CODEOWNERS +0 -0
  62. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/dependabot.yml +0 -0
  63. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/workflows/dependency-review.yml +0 -0
  64. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.github/workflows/secret-scan.yml +0 -0
  65. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.gitignore +0 -0
  66. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.gitleaks.toml +0 -0
  67. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/.mcpbignore +0 -0
  68. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/LICENSE +0 -0
  69. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/SECURITY.md +0 -0
  70. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/capture_sandbox_examples.py +0 -0
  71. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/check_dist.py +0 -0
  72. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/check_mcpb.py +0 -0
  73. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/check_release_artifacts.py +0 -0
  74. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/scripts/check_source_boundary.py +0 -0
  75. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/source-policy.public.json +0 -0
  76. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/conftest.py +0 -0
  77. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/fixtures/cloud-ts-signed-seal.json +0 -0
  78. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_approval_flow.py +0 -0
  79. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_attended_bridge.py +0 -0
  80. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_bridge.py +0 -0
  81. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_cards.py +0 -0
  82. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_cli.py +0 -0
  83. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_contract.py +0 -0
  84. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_mcp_server.py +0 -0
  85. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_partner_kit.py +0 -0
  86. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_runner.py +0 -0
  87. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_runs.py +0 -0
  88. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_sandbox_flow.py +0 -0
  89. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_seal.py +0 -0
  90. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_seal_cli.py +0 -0
  91. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_seal_e2e.py +0 -0
  92. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_service.py +0 -0
  93. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_skill.py +0 -0
  94. {openadapt_agent-2.1.0 → openadapt_agent-2.2.1}/tests/test_tutorial.py +0 -0
@@ -25,7 +25,7 @@ jobs:
25
25
  with:
26
26
  python-version: ${{ matrix.python-version }}
27
27
  cache: pip
28
- - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
28
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
29
29
  if: matrix.dependency-set == 'floor'
30
30
  - name: Verify lock consistency
31
31
  if: matrix.dependency-set == 'floor'
@@ -34,7 +34,7 @@ jobs:
34
34
  if: matrix.dependency-set == 'floor'
35
35
  run: >-
36
36
  pip install -e ".[dev]"
37
- "openadapt-flow==2.0.0"
37
+ "openadapt-flow==2.1.0"
38
38
  "mcp==1.28.0"
39
39
  - name: Install MCP 2 floor
40
40
  if: matrix.dependency-set == 'mcp2-floor'
@@ -78,3 +78,25 @@ jobs:
78
78
  DO_NOT_TRACK: "1"
79
79
  OPENADAPT_TELEMETRY: "0"
80
80
  run: pytest -q tests/test_sandbox_flow.py tests/test_approval_flow.py
81
+
82
+ repair-e2e:
83
+ # halt -> needs_repair -> teach_repair -> approval -> replay, on Flow's
84
+ # rendered dialog fixture with its real replayer, OCR, and campaigns.
85
+ runs-on: ubuntu-latest
86
+ steps:
87
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
88
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
89
+ with:
90
+ python-version: "3.12"
91
+ cache: pip
92
+ - name: Install with the released Flow (ships openadapt_flow.repair.dialog_fixture)
93
+ run: |
94
+ pip install -e ".[dev]" "openadapt-flow>=2.1.0,<3"
95
+ pip install opencv-python-headless rapidocr-onnxruntime
96
+ - name: Run the repair end-to-end test
97
+ env:
98
+ DO_NOT_TRACK: "1"
99
+ OPENADAPT_TELEMETRY: "0"
100
+ run: |
101
+ python -c "import openadapt_flow.repair.dialog_fixture"
102
+ pytest -q -rs tests/test_repair_e2e.py tests/test_repair_hold.py
@@ -28,10 +28,10 @@ jobs:
28
28
  - name: Checkout
29
29
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30
30
  - name: Initialize CodeQL
31
- uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
31
+ uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
32
32
  with:
33
33
  languages: ${{ matrix.language }}
34
34
  - name: Perform CodeQL Analysis
35
- uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
35
+ uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
36
36
  with:
37
37
  category: "/language:${{ matrix.language }}"
@@ -48,7 +48,7 @@ jobs:
48
48
  - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
49
49
  with:
50
50
  python-version: "3.12"
51
- - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
51
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
52
52
  with:
53
53
  node-version: "20"
54
54
  - name: Install tooling
@@ -94,13 +94,13 @@ jobs:
94
94
  sys.exit(1 if errors else 0)
95
95
  PY
96
96
  - name: Upload built distributions
97
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
97
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
98
98
  with:
99
99
  name: dist
100
100
  path: dist/
101
101
  if-no-files-found: error
102
102
  - name: Upload local MCPB
103
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
103
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
104
104
  with:
105
105
  name: mcpb
106
106
  path: mcpb-dist/
@@ -137,7 +137,7 @@ jobs:
137
137
  exit 1
138
138
  fi
139
139
  - name: Download built distributions
140
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
140
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
141
141
  with:
142
142
  name: dist
143
143
  path: dist/
@@ -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,19 +1,69 @@
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
- [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
4
- [![Python 3.10–3.12](https://img.shields.io/badge/python-3.10%E2%80%933.12-blue)](https://www.python.org/downloads/)
40
+ [![Packages CI](https://github.com/OpenAdaptAI/OpenAdapt/actions/workflows/packages.yml/badge.svg)](https://github.com/OpenAdaptAI/OpenAdapt/actions/workflows/packages.yml)
41
+ [![PyPI](https://img.shields.io/pypi/v/openadapt-agent)](https://pypi.org/project/openadapt-agent/)
42
+ [![Python](https://img.shields.io/pypi/pyversions/openadapt-agent)](https://pypi.org/project/openadapt-agent/)
43
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](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
 
8
47
  Use it if your agent reads referrals, intake forms, or authorizations and works out what belongs in the record, but a person still types the result into an app with no usable API. Examples are an electronic medical record (EMR) and a payer portal. This package is the tool your agent calls to do that typing.
9
48
 
10
- - A person records the task once in the real app. OpenAdapt replays those steps, and by default a run makes no AI model calls.
49
+ - A person or your agent shows OpenAdapt the task in the real app. OpenAdapt replays those steps, and by default a run makes no AI model calls.
11
50
  - Before it types, OpenAdapt checks that the right record is open. After it saves, it reads the record back.
12
51
  - Your agent gets one of four outcomes: done and checked, stopped before saving, check the record, or didn't run. When OpenAdapt can't confirm a save, it says so, and a person checks the record.
13
52
  - It runs on your customer's computer, one that can already open the app. Your agent, or a small program acting for it, has to run on that computer too, since it starts OpenAdapt and talks to it directly. If your agent runs in your own cloud, ask us about a hosted route.
14
53
 
15
54
  Pick one task your agent hands to staff today and [talk to us about connecting it](https://openadapt.ai/qualify?why=embed). Engineers can [try the sandbox](#try-it-in-three-steps) first.
16
55
 
56
+ ## Give your agent a program, not a mouse
57
+
58
+ Your agent doesn't send screenshots to a model and click. It calls a taught workflow as one typed tool, OpenAdapt runs the same steps every time, and by default your agent gets back an outcome and counts, not screens or recorded values.
59
+
60
+ ```bash
61
+ openadapt-agent serve --mode production --bundles <bundle or directory of bundles>
62
+ openadapt-agent emit-skill <bundle> --out ~/.claude/skills
63
+ ```
64
+
65
+ [Try it in three steps](#try-it-in-three-steps) runs a sandbox with no account. [Serve your own workflows](#serve-your-own-workflows) and [Write an Agent Skill](#write-an-agent-skill) cover both commands.
66
+
17
67
  ## What changes for your customer's team
18
68
 
19
69
  | Step | Today | With OpenAdapt |
@@ -42,28 +92,30 @@ flowchart LR
42
92
 
43
93
  | You build | OpenAdapt provides |
44
94
  | --- | --- |
45
- | The agent that reads documents and decides what to enter | A workflow built from one recording of a person doing the task in the real app |
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 |
46
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 |
47
97
  | What your product does with each outcome | One result per request, and no second entry when your agent repeats a `request_id` |
48
98
  | Your tests against the four outcomes | A sandbox that returns each outcome on demand |
49
99
 
50
- Your customer provides the computer and a person for runs that stop. Someone who does the task today records it once. Your agent can guide that recording (see [Record a first workflow](#record-a-first-workflow)), or [talk to us](https://openadapt.ai/qualify?why=embed) about setting it up.
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.
51
101
 
52
102
  ## Try it in three steps
53
103
 
54
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.
55
105
 
56
- You need [Claude Code](https://claude.com/claude-code) (signed in), [uv](https://docs.astral.sh/uv/), and git. To use a different client or your own code, see [Connect your own agent](#connect-your-own-agent).
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).
57
107
 
58
- 1. Add the sandbox server. Claude Code saves it for the current folder only.
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.
59
109
 
60
110
  ```bash
61
- claude mcp add openadapt -- uvx --python 3.12 --from git+https://github.com/OpenAdaptAI/openadapt-agent openadapt-agent serve
111
+ claude mcp add --scope user openadapt -- uvx --python 3.12 openadapt-agent serve
62
112
  ```
63
113
 
64
- 2. In the same folder, start Claude Code with `claude`. Claude Code starts the server.
114
+ This only registers the server. It prints one line saying the server was added to user config, and nothing else.
65
115
 
66
- 3. Ask: "Use OpenAdapt to add the triage note 'Synthetic: recheck blood pressure in 2 weeks' with request id demo-0001."
116
+ 2. Start Claude Code with `claude`. Claude Code starts the server. Optional: type `/mcp` to check that `openadapt` is connected.
117
+
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."
67
119
 
68
120
  Your agent should call `list_workflows`, then `run_workflow` with these arguments:
69
121
 
@@ -88,17 +140,17 @@ The result looks like this (some fields left out):
88
140
 
89
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).
90
142
 
91
- PyPI has version 2.0.1, which came out before the sandbox. After 2.1.0 is on PyPI, step 1 can be `claude mcp add openadapt -- uvx --python 3.12 openadapt-agent serve`.
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.
92
144
 
93
145
  ### See every outcome
94
146
 
95
- Ask for each case by adding `sandbox_case` to the inputs, with a new `request_id` each time. For example: "Now try the false_saved_banner case with request id demo-0002."
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."
96
148
 
97
149
  | `sandbox_case` | `outcome` | What MockMed does |
98
150
  | --- | --- | --- |
99
151
  | `normal` (default) | `done` | Saves the note, and the record check finds it. |
100
152
  | `duplicate_record` | `needs_review` | Lists the same referral twice, so OpenAdapt can't tell which record to open. It stops before saving. |
101
- | `false_saved_banner` | `not_sure_if_saved` | Shows a saved message, but the note wasn't stored. |
153
+ | `false_saved_banner` | `not_sure_if_saved` | Rejects the note on save, so it isn't stored. |
102
154
  | `timeout_after_save` | `not_sure_if_saved` | Saves the note, then times out with an error. |
103
155
  | `app_offline` | `did_not_run` | Doesn't answer, so nothing starts. |
104
156
 
@@ -106,16 +158,16 @@ The sandbox remembers each `request_id` across sessions. Sending a used `request
106
158
 
107
159
  ### Drive MockMed with the real engine
108
160
 
109
- 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`:
110
162
 
111
163
  ```bash
112
164
  claude mcp remove openadapt
113
- claude mcp add openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial] @ git+https://github.com/OpenAdaptAI/openadapt-agent' openadapt-agent serve
165
+ claude mcp add --scope user openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve
114
166
  ```
115
167
 
116
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"`.
117
169
 
118
- Until 2.1.0 is on PyPI, use the command above. The simulated sandbox suggests the same command in its `list_workflows` result. A command that installs `openadapt-agent[tutorial]` from PyPI gets 2.0.1, which has no sandbox: the server exits with an error that `--bundles` is required.
170
+ The simulated sandbox suggests the same command in its `list_workflows` result.
119
171
 
120
172
  ## What your agent gets back
121
173
 
@@ -146,11 +198,12 @@ The check that stops a second entry covers one runs folder. See `--runs-dir` und
146
198
  ### Read the other fields
147
199
 
148
200
  - `label`: a short status you can display, such as "Done and checked".
149
- - `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](src/openadapt_agent/contract.py), and [docs/DESIGN.md](docs/DESIGN.md#the-result-contract) explains how each one is chosen.
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.
150
202
  - `what_happened` and `next_action`: fixed sentences you can show a person. They never contain input values or screen text.
151
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.
152
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)).
153
205
  - `record_changed`: `yes`, `no`, or `unknown`. It's `no` only when OpenAdapt can show that nothing was written. `request_id_conflict` gives `unknown`, because the earlier request may have saved.
206
+ - `needs_repair`: on `needs_review` or `did_not_run` results where the run stopped at a step. It gives the step id, the reason, and a one-time `repair_token`, and never a screen. If a person turned on screen access for repairs, your agent can call `get_repair_screen` and `teach_repair` to propose a fix, which a person must approve. See [docs/REPAIR.md](docs/REPAIR.md).
154
207
 
155
208
  ## Three tools
156
209
 
@@ -168,7 +221,7 @@ The sandbox has all three tools. With your own workflows, `run_workflow` appears
168
221
 
169
222
  ## Developer setup
170
223
 
171
- 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-flow) records, replays, and checks the workflows.
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.
172
225
 
173
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`.
174
227
 
@@ -181,7 +234,7 @@ Any MCP client can start the server with the command `uvx`. In a client that rea
181
234
  "mcpServers": {
182
235
  "openadapt": {
183
236
  "command": "uvx",
184
- "args": ["--python", "3.12", "--from", "git+https://github.com/OpenAdaptAI/openadapt-agent", "openadapt-agent", "serve"]
237
+ "args": ["--python", "3.12", "openadapt-agent", "serve"]
185
238
  }
186
239
  }
187
240
  }
@@ -198,8 +251,7 @@ from mcp.client.stdio import stdio_client
198
251
 
199
252
  SERVER = StdioServerParameters(
200
253
  command="uvx",
201
- args=["--python", "3.12", "--from", "git+https://github.com/OpenAdaptAI/openadapt-agent",
202
- "openadapt-agent", "serve"],
254
+ args=["--python", "3.12", "openadapt-agent", "serve"],
203
255
  )
204
256
 
205
257
 
@@ -224,7 +276,7 @@ The SDK starts the server with only a few environment variables. To pass others,
224
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:
225
277
 
226
278
  ```bash
227
- python scripts/smoke_client.py -- uvx --python 3.12 --from git+https://github.com/OpenAdaptAI/openadapt-agent openadapt-agent serve
279
+ python scripts/smoke_client.py -- uvx --python 3.12 openadapt-agent serve
228
280
  ```
229
281
 
230
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).
@@ -242,7 +294,7 @@ A bundle is a compiled workflow folder that contains `workflow.json`, or `workfl
242
294
 
243
295
  `openadapt-agent serve --allow-run` is the older form of `--mode production`, or of the sandbox when there's no `--bundles`.
244
296
 
245
- 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-flow#readme) covers each kind of app.
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.
246
298
 
247
299
  ### Get a workflow ready to run
248
300
 
@@ -254,7 +306,7 @@ What Flow requires depends on the profile set in the deployment config (`--confi
254
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`.
255
307
  - `demo`: no certification, but Flow doesn't confirm the save, so a finished run ends `not_sure_if_saved`.
256
308
 
257
- Flow's [execution profiles](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/EXECUTION_PROFILES.md) page explains each profile.
309
+ Flow's [execution profiles](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/packages/flow/docs/EXECUTION_PROFILES.md) page explains each profile.
258
310
 
259
311
  ### Set server options
260
312
 
@@ -262,10 +314,11 @@ Flow's [execution profiles](https://github.com/OpenAdaptAI/openadapt-flow/blob/m
262
314
  | --- | --- |
263
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. |
264
316
  | `--url URL` | The app's address, passed to every Flow run. |
265
- | `--config YAML` | Flow's deployment config ([example](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/deployment.example.yaml)), which sets the profile and whether model grounding is allowed. |
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. |
266
318
  | `--policy NAME-OR-PATH` | The policy Flow certifies against, such as `clinical-write` or `permissive`. |
267
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`. |
268
- | `--approval-mode MODE` | Whether a person approves each save. Without it, Flow decides: under `standard` and `regulated` a run stops before each save until a person approves it (`each_item`). `not_gated` turns that off for every run this server starts; each result records it under `technical.approval_mode`. |
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). |
269
322
  | `--headed` | Shows the browser. A person needs it to continue or skip a stopped run in a web app. |
270
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`. |
271
324
  | `--allow-protected-export`, `--allow-synthetic-recorded-defaults`, `--allow-model-grounding` | Off by default. See [Security](#security). |
@@ -280,7 +333,7 @@ Under `standard` and `regulated`, Flow stops before each save and waits for a pe
280
333
 
281
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.
282
335
 
283
- `list_workflows`, `run_workflow`, and `get_run` return `structuredContent` that matches their `outputSchema`, defined in [contract.py](src/openadapt_agent/contract.py), plus the same JSON as text.
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.
284
337
 
285
338
  ### Decide stopped runs
286
339
 
@@ -325,26 +378,40 @@ If a workflow's name would come out as either one, emit-skill names the skill `o
325
378
 
326
379
  ### Record a first workflow
327
380
 
328
- `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. Your agent uses them to help a person record a task in a web app. The recording server doesn't turn on runs.
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.
329
382
 
330
- 1. Add a recording server. `--url` opens the app in a new Chromium window with no saved sign-ins, and `--headed` keeps that window visible so the person can sign in.
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.
331
384
 
332
385
  ```bash
333
- claude mcp add openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial] @ git+https://github.com/OpenAdaptAI/openadapt-agent' openadapt-agent serve --authoring --url https://app.example.com --headed
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
334
387
  ```
335
388
 
336
- 2. 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.
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.
337
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.
338
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.
339
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`.
340
395
 
341
- 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. For Windows desktop apps, Citrix, and RDP, the recording tools can only tell the person what to click. Record those apps with Flow's own recorder.
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.
342
397
 
343
- ChatGPT and Claude in a web browser can't start a server on your computer. To record from one of them, start at https://openadapt.ai/start. When openadapt.ai gives you a runner link for the recording job (it contains `bind=oab_`), run this on the computer that has the app:
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.
344
399
 
345
- ```bash
346
- openadapt-agent authoring connect '<runner link>'
347
- ```
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
+ ```
348
415
 
349
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.
350
417
 
@@ -390,19 +457,19 @@ openadapt-agent seal verify https://example.com/receipt.json --json
390
457
  - The check that stops a second entry covers one runs folder. Pass the same absolute `--runs-dir` every time.
391
458
  - If the server exits during a run, the run reads as `not_sure_if_saved`, and Flow may still finish it.
392
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)).
393
- - With openadapt-flow 2, every save waits for a person's 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`, and a person approves on the computer that runs OpenAdapt. Nothing is saved without that answer.
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.
394
461
  - Each call carries one request. There's no batch call.
395
462
  - Accounts, separation between customers, fleet policy, and hosted runs belong to OpenAdapt Cloud.
396
463
 
397
464
  ## Release status
398
465
 
399
- The [signed production record](https://openadapt.ai/production-lifecycle.json) says whether a release of this package is admitted for production use. An admission lasts at most 30 days and can be revoked, and a release without a valid one is "not actively admitted." On 2026-10-14, no release of this package was admitted. The admission for 2.0.1 was issued on 2026-09-02 and is past the 30-day limit, and the version on GitHub (2.1.0) has none. Check the record before you use a release with real patient data.
466
+ Check the [signed production record](https://openadapt.ai/production-lifecycle.json) before you use a release with real patient data. An admission lasts at most 30 days and can be revoked.
400
467
 
401
468
  Under Flow's `standard` and `regulated` profiles, each workflow version also needs its own admission (see [Get a workflow ready to run](#get-a-workflow-ready-to-run)). On 2026-10-14, every entry in the [public list of workflow admissions](https://openadapt.ai/production-workflow-admissions.json) came from synthetic tests (`remote-safe-synthetic`).
402
469
 
403
470
  ## Package history
404
471
 
405
- 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).
406
473
 
407
474
  <!-- mcp-name: io.github.OpenAdaptAI/openadapt-agent -->
408
475