openadapt-agent 2.0.0__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 (40) hide show
  1. openadapt_agent-2.0.0/.github/CODEOWNERS +2 -0
  2. openadapt_agent-2.0.0/.github/dependabot.yml +17 -0
  3. openadapt_agent-2.0.0/.github/workflows/ci.yml +34 -0
  4. openadapt_agent-2.0.0/.github/workflows/codeql.yml +37 -0
  5. openadapt_agent-2.0.0/.github/workflows/dependency-review.yml +21 -0
  6. openadapt_agent-2.0.0/.github/workflows/release.yml +206 -0
  7. openadapt_agent-2.0.0/.github/workflows/secret-scan.yml +32 -0
  8. openadapt_agent-2.0.0/.gitignore +139 -0
  9. openadapt_agent-2.0.0/LICENSE +21 -0
  10. openadapt_agent-2.0.0/PKG-INFO +331 -0
  11. openadapt_agent-2.0.0/README.md +298 -0
  12. openadapt_agent-2.0.0/SECURITY.md +35 -0
  13. openadapt_agent-2.0.0/docs/DESIGN.md +270 -0
  14. openadapt_agent-2.0.0/docs/DISTRIBUTION.md +237 -0
  15. openadapt_agent-2.0.0/llms.txt +44 -0
  16. openadapt_agent-2.0.0/pyproject.toml +69 -0
  17. openadapt_agent-2.0.0/scripts/check_dist.py +110 -0
  18. openadapt_agent-2.0.0/scripts/check_release_artifacts.py +132 -0
  19. openadapt_agent-2.0.0/scripts/smoke_client.py +70 -0
  20. openadapt_agent-2.0.0/server.json +53 -0
  21. openadapt_agent-2.0.0/smithery.yaml +87 -0
  22. openadapt_agent-2.0.0/src/openadapt_agent/__init__.py +24 -0
  23. openadapt_agent-2.0.0/src/openadapt_agent/__main__.py +6 -0
  24. openadapt_agent-2.0.0/src/openadapt_agent/attended.py +376 -0
  25. openadapt_agent-2.0.0/src/openadapt_agent/bridge.py +464 -0
  26. openadapt_agent-2.0.0/src/openadapt_agent/bundles.py +195 -0
  27. openadapt_agent-2.0.0/src/openadapt_agent/cli.py +266 -0
  28. openadapt_agent-2.0.0/src/openadapt_agent/flow_service.py +51 -0
  29. openadapt_agent-2.0.0/src/openadapt_agent/mcp.py +186 -0
  30. openadapt_agent-2.0.0/src/openadapt_agent/runner.py +477 -0
  31. openadapt_agent-2.0.0/src/openadapt_agent/skill.py +113 -0
  32. openadapt_agent-2.0.0/tests/conftest.py +128 -0
  33. openadapt_agent-2.0.0/tests/golden/skill_appendix.md +65 -0
  34. openadapt_agent-2.0.0/tests/test_attended_bridge.py +513 -0
  35. openadapt_agent-2.0.0/tests/test_bridge.py +396 -0
  36. openadapt_agent-2.0.0/tests/test_cli.py +58 -0
  37. openadapt_agent-2.0.0/tests/test_distribution.py +143 -0
  38. openadapt_agent-2.0.0/tests/test_mcp_server.py +218 -0
  39. openadapt_agent-2.0.0/tests/test_runner.py +184 -0
  40. openadapt_agent-2.0.0/tests/test_skill.py +47 -0
@@ -0,0 +1,2 @@
1
+ # Default code owners. Enforced via branch protection (required review).
2
+ * @abrichr
@@ -0,0 +1,17 @@
1
+ # SOC 2: automated dependency updates (OA-C-23).
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "pip"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ open-pull-requests-limit: 5
9
+ labels:
10
+ - "dependencies"
11
+ - package-ecosystem: "github-actions"
12
+ directory: "/"
13
+ schedule:
14
+ interval: "weekly"
15
+ open-pull-requests-limit: 5
16
+ labels:
17
+ - "dependencies"
@@ -0,0 +1,34 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v7
17
+ - uses: actions/setup-python@v7
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ cache: pip
21
+ - name: Install
22
+ run: pip install -e ".[dev]"
23
+ - name: Lint
24
+ run: ruff check src tests scripts
25
+ - name: Test
26
+ run: pytest -q
27
+ - name: Build release artifacts
28
+ if: matrix.python-version == '3.12'
29
+ run: python -m build
30
+ - name: Verify MIT package boundary
31
+ if: matrix.python-version == '3.12'
32
+ run: |
33
+ python scripts/check_release_artifacts.py dist
34
+ python scripts/check_dist.py dist/*
@@ -0,0 +1,37 @@
1
+ name: CodeQL
2
+
3
+ # SOC 2: SAST (OA-C-24). Static analysis on push/PR to main + weekly.
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+ schedule:
10
+ - cron: "23 5 * * 1"
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ analyze:
17
+ name: Analyze (${{ matrix.language }})
18
+ runs-on: ubuntu-latest
19
+ permissions:
20
+ security-events: write
21
+ actions: read
22
+ contents: read
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ language: ["python"]
27
+ steps:
28
+ - name: Checkout
29
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30
+ - name: Initialize CodeQL
31
+ uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
32
+ with:
33
+ languages: ${{ matrix.language }}
34
+ - name: Perform CodeQL Analysis
35
+ uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
36
+ with:
37
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,21 @@
1
+ name: Dependency Review
2
+
3
+ # SOC 2: dependency-review (OA-C-24). Flags vulnerable/denied deps on PRs.
4
+ on:
5
+ pull_request:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ dependency-review:
13
+ name: dependency-review
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
18
+ - name: Dependency Review
19
+ uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
20
+ with:
21
+ fail-on-severity: high
@@ -0,0 +1,206 @@
1
+ name: Release
2
+
3
+ # Builds the package, gates it on the license/boundary check, and — ONLY on
4
+ # a version tag or a published GitHub Release — publishes to PyPI and to the
5
+ # official MCP registry. A normal push or PR runs the validate job only
6
+ # (dry run, no publish), so the workflow itself is testable without shipping.
7
+ #
8
+ # Auth is OIDC-first and secret-free for the io.github.OpenAdaptAI namespace:
9
+ # - PyPI: Trusted Publishing (needs a one-time publisher config on PyPI +
10
+ # a GitHub environment named `pypi`; NO repo secret).
11
+ # - MCP registry: `mcp-publisher login github-oidc` (NO repo secret).
12
+ # Optional token fallbacks are wired and fail LOUD if selected-but-unset;
13
+ # see docs/DISTRIBUTION.md.
14
+
15
+ on:
16
+ push:
17
+ tags: ["v*"]
18
+ release:
19
+ types: [published]
20
+ workflow_dispatch:
21
+ pull_request:
22
+ paths:
23
+ - "pyproject.toml"
24
+ - "server.json"
25
+ - "smithery.yaml"
26
+ - "scripts/check_release_artifacts.py"
27
+ - "scripts/check_dist.py"
28
+ - ".github/workflows/release.yml"
29
+
30
+ concurrency:
31
+ group: release-${{ github.ref }}
32
+ cancel-in-progress: false
33
+
34
+ permissions:
35
+ contents: read
36
+
37
+ jobs:
38
+ validate:
39
+ name: Build + validate (dry run, no publish)
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v5
43
+ - uses: actions/setup-python@v6
44
+ with:
45
+ python-version: "3.12"
46
+ - name: Install tooling
47
+ run: |
48
+ python -m pip install --upgrade pip
49
+ python -m pip install --upgrade build "twine>=6.1" "packaging>=24.2" jsonschema
50
+ python -m pip install -e ".[dev]"
51
+ - name: Version-consistency guard (server.json / pyproject / __version__)
52
+ run: python -m pytest tests/test_distribution.py -q
53
+ - name: Build sdist + wheel
54
+ run: python -m build
55
+ - name: License / package-boundary check on built archives
56
+ run: |
57
+ python scripts/check_release_artifacts.py dist
58
+ python scripts/check_dist.py dist/*
59
+ - name: twine check
60
+ run: twine check dist/*
61
+ - name: Validate server.json against the MCP registry schema
62
+ run: |
63
+ python - <<'PY'
64
+ import json, sys, urllib.request
65
+ from jsonschema import Draft202012Validator
66
+ doc = json.load(open("server.json"))
67
+ url = doc["$schema"]
68
+ try:
69
+ schema = json.load(urllib.request.urlopen(url, timeout=30))
70
+ except Exception as exc: # network hiccup: don't fail the dry run
71
+ print(f"WARNING: could not fetch {url}: {exc}; skipping live schema check")
72
+ sys.exit(0)
73
+ errors = sorted(Draft202012Validator(schema).iter_errors(doc), key=lambda e: list(e.path))
74
+ for e in errors:
75
+ print("SCHEMA ERROR:", list(e.path), e.message)
76
+ sys.exit(1 if errors else 0)
77
+ PY
78
+ - name: Upload built distributions
79
+ uses: actions/upload-artifact@v4
80
+ with:
81
+ name: dist
82
+ path: dist/
83
+ if-no-files-found: error
84
+
85
+ pypi-publish:
86
+ name: Publish to PyPI
87
+ needs: validate
88
+ if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || github.event_name == 'release' }}
89
+ runs-on: ubuntu-latest
90
+ environment: pypi
91
+ permissions:
92
+ id-token: write # OIDC for PyPI Trusted Publishing
93
+ contents: read
94
+ steps:
95
+ - uses: actions/checkout@v5
96
+ - name: Resolve release version + assert it matches the package
97
+ id: ver
98
+ shell: bash
99
+ run: |
100
+ set -euo pipefail
101
+ if [ "${{ github.event_name }}" = "release" ]; then
102
+ tag="${{ github.event.release.tag_name }}"
103
+ else
104
+ tag="${GITHUB_REF#refs/tags/}"
105
+ fi
106
+ tag_version="${tag#v}"
107
+ pkg_version="$(grep -m1 -E '^version = ' pyproject.toml | sed -E 's/version = "(.*)"/\1/')"
108
+ echo "version=${pkg_version}" >> "$GITHUB_OUTPUT"
109
+ if [ "${tag_version}" != "${pkg_version}" ]; then
110
+ echo "::error::Tag version '${tag_version}' != pyproject version '${pkg_version}'." \
111
+ "Bump pyproject.toml, __init__.py, and server.json together (the" \
112
+ "tests/test_distribution.py guard pins them) and re-tag." >&2
113
+ exit 1
114
+ fi
115
+ - name: Download built distributions
116
+ uses: actions/download-artifact@v5
117
+ with:
118
+ name: dist
119
+ path: dist/
120
+ - name: Fail loud if token method selected without a token
121
+ if: ${{ vars.PYPI_PUBLISH_METHOD == 'token' }}
122
+ env:
123
+ TOKEN: ${{ secrets.PYPI_API_TOKEN }}
124
+ run: |
125
+ if [ -z "${TOKEN}" ]; then
126
+ echo "::error::PYPI_PUBLISH_METHOD is 'token' but the repo secret" \
127
+ "PYPI_API_TOKEN is not set. Add it, or unset the variable to use" \
128
+ "OIDC Trusted Publishing (recommended)." >&2
129
+ exit 1
130
+ fi
131
+ - name: Publish to PyPI (OIDC Trusted Publishing)
132
+ if: ${{ vars.PYPI_PUBLISH_METHOD != 'token' }}
133
+ uses: pypa/gh-action-pypi-publish@release/v1
134
+ with:
135
+ # No password -> the action uses OIDC Trusted Publishing.
136
+ print-hash: true
137
+ - name: Publish to PyPI (API token fallback)
138
+ if: ${{ vars.PYPI_PUBLISH_METHOD == 'token' }}
139
+ uses: pypa/gh-action-pypi-publish@release/v1
140
+ with:
141
+ password: ${{ secrets.PYPI_API_TOKEN }}
142
+ print-hash: true
143
+
144
+ mcp-registry-publish:
145
+ name: Publish server.json to the MCP registry
146
+ needs: [validate, pypi-publish]
147
+ if: ${{ (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || github.event_name == 'release' }}
148
+ runs-on: ubuntu-latest
149
+ permissions:
150
+ id-token: write # OIDC for `mcp-publisher login github-oidc`
151
+ contents: read
152
+ steps:
153
+ - uses: actions/checkout@v5
154
+ - name: Resolve release version
155
+ id: ver
156
+ shell: bash
157
+ run: |
158
+ set -euo pipefail
159
+ pkg_version="$(grep -m1 -E '^version = ' pyproject.toml | sed -E 's/version = "(.*)"/\1/')"
160
+ echo "version=${pkg_version}" >> "$GITHUB_OUTPUT"
161
+ - name: Wait for the PyPI package to be installable
162
+ shell: bash
163
+ run: |
164
+ set -euo pipefail
165
+ version="${{ steps.ver.outputs.version }}"
166
+ url="https://pypi.org/pypi/openadapt-agent/${version}/json"
167
+ for attempt in $(seq 1 20); do
168
+ code="$(curl -s -o /dev/null -w '%{http_code}' "$url")"
169
+ if [ "$code" = "200" ]; then
170
+ echo "openadapt-agent ${version} is live on PyPI."
171
+ exit 0
172
+ fi
173
+ echo "Attempt ${attempt}: PyPI returned ${code} for ${version}; waiting 15s..."
174
+ sleep 15
175
+ done
176
+ echo "::error::openadapt-agent ${version} did not appear on PyPI in time." \
177
+ "The MCP registry validates package existence, so it would reject" \
178
+ "this publish. Check the PyPI publish job." >&2
179
+ exit 1
180
+ - name: Install mcp-publisher
181
+ shell: bash
182
+ run: |
183
+ set -euo pipefail
184
+ os="$(uname -s | tr '[:upper:]' '[:lower:]')"
185
+ arch="$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
186
+ curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_${os}_${arch}.tar.gz" \
187
+ | tar xz mcp-publisher
188
+ - name: Fail loud if token method selected without a token
189
+ if: ${{ vars.MCP_PUBLISH_METHOD == 'token' }}
190
+ env:
191
+ TOKEN: ${{ secrets.MCP_GITHUB_TOKEN }}
192
+ run: |
193
+ if [ -z "${TOKEN}" ]; then
194
+ echo "::error::MCP_PUBLISH_METHOD is 'token' but the repo secret" \
195
+ "MCP_GITHUB_TOKEN is not set. Add a PAT with read:org + read:user," \
196
+ "or unset the variable to use OIDC (recommended)." >&2
197
+ exit 1
198
+ fi
199
+ - name: Authenticate to the MCP registry (OIDC)
200
+ if: ${{ vars.MCP_PUBLISH_METHOD != 'token' }}
201
+ run: ./mcp-publisher login github-oidc
202
+ - name: Authenticate to the MCP registry (PAT fallback)
203
+ if: ${{ vars.MCP_PUBLISH_METHOD == 'token' }}
204
+ run: ./mcp-publisher login github --token "${{ secrets.MCP_GITHUB_TOKEN }}"
205
+ - name: Publish server.json
206
+ run: ./mcp-publisher publish
@@ -0,0 +1,32 @@
1
+ name: Secret Scan
2
+
3
+ # SOC 2: secret scanning (OA-C-24). Uses the free, MIT-licensed gitleaks CLI.
4
+ # NOTE: the gitleaks *Action* now requires a paid GITLEAKS_LICENSE for
5
+ # organization-owned repos (even public ones); the gitleaks CLI does not, so we
6
+ # invoke it directly and pin the version. Scans full git history on PRs + main.
7
+ on:
8
+ pull_request:
9
+ push:
10
+ branches: [main]
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ gitleaks:
17
+ name: gitleaks
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - name: Checkout
21
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+ with:
23
+ fetch-depth: 0
24
+ - name: Install gitleaks
25
+ env:
26
+ GITLEAKS_VERSION: 8.30.1
27
+ run: |
28
+ curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
29
+ | tar -xz -C /usr/local/bin gitleaks
30
+ gitleaks version
31
+ - name: Scan git history for secrets
32
+ run: gitleaks git . --redact --no-banner
@@ -0,0 +1,139 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Django stuff:
54
+ *.log
55
+ local_settings.py
56
+
57
+ # Flask stuff:
58
+ instance/
59
+ .webassets-cache
60
+
61
+ # Scrapy stuff:
62
+ .scrapy
63
+
64
+ # Sphinx documentation
65
+ docs/_build/
66
+
67
+ # PyBuilder
68
+ target/
69
+
70
+ # Jupyter Notebook
71
+ .ipynb_checkpoints
72
+
73
+ # IPython
74
+ profile_default/
75
+ ipython_config.py
76
+
77
+ # pyenv
78
+ .python-version
79
+
80
+ # pipenv
81
+ Pipfile.lock
82
+
83
+ # PEP 582
84
+ __pypackages__/
85
+
86
+ # Celery stuff
87
+ celerybeat-schedule
88
+ celerybeat.pid
89
+
90
+ # SageMath parsed files
91
+ *.sage.py
92
+
93
+ # Environments
94
+ .env
95
+ .venv
96
+ env/
97
+ venv/
98
+ ENV/
99
+ env.bak/
100
+ venv.bak/
101
+
102
+ # Spyder project settings
103
+ .spyderproject
104
+ .spyproject
105
+
106
+ # Rope project settings
107
+ .ropeproject
108
+
109
+ # mkdocs documentation
110
+ /site
111
+
112
+ # mypy
113
+ .mypy_cache/
114
+ .dmypy.json
115
+ dmypy.json
116
+
117
+ # Pyre type checker
118
+ .pyre/
119
+
120
+ # ruff
121
+ .ruff_cache/
122
+
123
+ # uv
124
+ uv.lock
125
+
126
+ # IDE
127
+ .idea/
128
+ .vscode/
129
+ *.swp
130
+ *.swo
131
+ *~
132
+
133
+ # OS
134
+ .DS_Store
135
+ Thumbs.db
136
+
137
+ # Project specific
138
+ *.session.json
139
+ sessions/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MLDSAI Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.