You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore(nox): centralize dependency pins in pyproject.toml
Migrate all nox session dependency pins and package metadata into
py/pyproject.toml as the single source of truth:
- Replace setup.py with pyproject.toml (setuptools backend)
- Move base test deps, session auxiliary deps, lint deps, build deps,
and dev deps into PEP 735 dependency groups
- Move provider version matrices into [tool.braintrust.matrix] custom
table (read by noxfile at import time)
- Generate and commit uv.lock for reproducible auxiliary dep resolution
- Pin all previously-floating 'latest' versions to explicit versions
- Remove requirements-dev.txt, requirements-build.txt,
requirements-optional.txt, and the install-optional Makefile target
- Switch Makefile and CI from uv pip install to uv sync
- Bump uv to 0.11.6 in .tool-versions
- Add weekly dependency-updates.yml workflow that runs uv lock --upgrade
and labels PRs based on whether provider SDKs changed
- Exclude uv.lock from codespell checks (false positive on astroid)
- Update AGENTS.md, CONTRIBUTING.md, and agent skill docs to reflect
the new layout
@@ -37,7 +38,7 @@ These rules must stay aligned with `AGENTS.md`:
37
38
38
39
- Work from `py/` for SDK tasks.
39
40
- Use `mise` as the source of truth for tools and environment.
40
-
- Do not guess nox session names or provider/version coverage.
41
+
- Do not guess nox session names or provider/version coverage. Provider version pins (including what "latest" resolves to) are in `py/pyproject.toml``[tool.braintrust.matrix]`.
41
42
- Default bug-fix workflow is red -> green.
42
43
- Prefer VCR-backed provider tests over mocks or fakes whenever practical.
43
44
- Treat mock/fake tests for provider behavior as an exception that requires justification, not as a neutral alternative.
Automated daily dependency update via `uv lock --upgrade`.
78
+
79
+
${{ steps.labels.outputs.needs_rerecord == 'true' && '⚠️ **Provider SDK packages changed.** A human needs to re-record cassettes locally before merging.' || '✅ Only test infrastructure deps changed. Safe to merge if CI passes.' }}
Copy file name to clipboardExpand all lines: AGENTS.md
+29-7Lines changed: 29 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,8 @@ Use this file as the default playbook for work in this repository.
15
15
2.**Use `mise` as the source of truth for tools and environment.**
16
16
17
17
3.**Do not guess test commands or version coverage.**
18
-
-`py/noxfile.py` is the source of truth for nox session names, provider/version matrices, and local reproduction commands.
18
+
-`py/pyproject.toml``[tool.braintrust.matrix]` is the source of truth for provider version pins (including what "latest" resolves to).
19
+
-`py/noxfile.py` reads those pins and is the source of truth for nox session names, parametrized version matrices, and local reproduction commands.
19
20
-`.github/workflows/checks.yaml` is the source of truth for which sessions run in CI, on which Python versions, and outside vs. inside the nox shard matrix.
20
21
- For provider and integration work, also check `py/src/braintrust/integrations/versioning.py`.
21
22
@@ -42,6 +43,8 @@ Use this file as the default playbook for work in this repository.
42
43
## Repo Map
43
44
44
45
-`py/`: main Python package, tests, examples, nox sessions, build/release workflow
46
+
-`py/pyproject.toml`: single source of truth for package metadata, dependency groups, and provider version matrix
47
+
-`py/uv.lock`: committed lockfile for reproducible auxiliary dep resolution
45
48
-`py/src/braintrust/`: SDK source
46
49
- top-level package files: core SDK
47
50
-`wrappers/`: wrappers
@@ -70,12 +73,7 @@ cd py
70
73
make install-dev
71
74
```
72
75
73
-
Install optional provider dependencies only when needed:
74
-
75
-
```bash
76
-
cd py
77
-
make install-optional
78
-
```
76
+
Note: `install-dev` uses `uv sync` under the hood, reading dependency groups from `py/pyproject.toml`. There is no separate `requirements-dev.txt`.
Only re-record HTTP or subprocess cassettes when the behavior change is intentional. If unsure, ask the user.
238
236
237
+
Stale cassette detection:
238
+
239
+
- When versions are dropped from `[tool.braintrust.matrix]`, their cassette subdirectories become orphaned.
240
+
-`py/scripts/check-stale-cassettes.py` compares on-disk cassette version directories against the matrix.
241
+
- The mapping from integration directory name to matrix key(s) lives in `[tool.braintrust.cassette-dirs]` in `py/pyproject.toml`.
242
+
- Runs automatically via pre-commit hook (triggers on `pyproject.toml` or `cassettes/` changes).
243
+
- Manual check: `cd py && make check-stale-cassettes`
244
+
- To auto-delete stale dirs: `cd py && python scripts/check-stale-cassettes.py --clean`
245
+
- When adding a new integration with versioned cassettes, add an entry to `[tool.braintrust.cassette-dirs]`.
246
+
239
247
## Benchmarks
240
248
241
249
If you touch a hot path such as serialization, deep-copy, span creation, or logging, consider benchmarks.
@@ -270,13 +278,27 @@ cd py
270
278
make build
271
279
```
272
280
281
+
The build uses `pyproject.toml` with the setuptools backend. There is no `setup.py`.
282
+
273
283
Caveat:
274
284
275
285
-`py/scripts/template-version.py` rewrites `py/src/braintrust/version.py` during build
276
286
-`py/Makefile` restores that file afterward with `git checkout`
277
287
278
288
Avoid editing `py/src/braintrust/version.py` while also running build commands.
279
289
290
+
## Dependency Pinning
291
+
292
+
All nox session dependency pins are centralized in `py/pyproject.toml`:
293
+
294
+
-**`[dependency-groups]`** (PEP 735): base test deps, session-specific auxiliary deps (e.g. `test-litellm`, `test-langchain`), lint deps, build deps, and dev deps. These participate in `uv lock` and produce `py/uv.lock`.
295
+
-**`[tool.braintrust.matrix]`**: provider version matrix pins (e.g. `openai`, `anthropic`). Each provider has a `latest` key pinned to an explicit version and additional older version keys. The noxfile reads these at import time to derive the parametrized version tuples.
296
+
-**`[tool.uv.conflicts]`**: declares which dependency groups cannot coexist in one resolution (e.g. groups pinning different `openai` versions).
297
+
298
+
The `LATEST` sentinel in the noxfile maps to the `latest` key in the matrix table — it is no longer a floating install.
299
+
300
+
A daily GitHub Actions workflow (`.github/workflows/dependency-updates.yml`) runs `uv lock --upgrade`, classifies changes by reading group names from `pyproject.toml`, and opens a PR labeled `needs-cassette-rerecord` (provider SDK bumps) or `auto-merge-candidate` (infra-only bumps).
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+8-9Lines changed: 8 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,10 +23,12 @@ If you use `mise activate` in your shell, entering the repo will automatically e
23
23
## Repo Layout
24
24
25
25
-`py/`: main Python SDK
26
+
-`py/pyproject.toml`: single source of truth for package metadata, dependency groups, and provider version matrix
27
+
-`py/uv.lock`: committed lockfile for reproducible auxiliary dep resolution
26
28
-`integrations/`: separate integration packages such as LangChain and ADK
27
29
-`docs/`: supporting docs
28
30
29
-
Most SDK changes should happen under `py/`.
31
+
Most SDK changes should happen under `py/`. There is no `setup.py` — `pyproject.toml` is the build configuration.
30
32
31
33
## Common Workflows
32
34
@@ -40,6 +42,8 @@ make lint
40
42
nox -l
41
43
```
42
44
45
+
`make install-dev` uses `uv sync` under the hood, reading dependency groups from `py/pyproject.toml`. There are no separate `requirements-*.txt` files.
Install optional provider packages only when you need them:
58
-
59
-
```bash
60
-
cd py
61
-
make install-optional
62
-
```
61
+
Optional provider packages are installed automatically by each nox session — there is no separate `install-optional` target.
63
62
64
63
### Repo-Level Commands
65
64
@@ -95,7 +94,7 @@ uv run pytest
95
94
96
95
## Testing Notes
97
96
98
-
The SDK uses [nox](https://nox.thea.codes/) for compatibility testing across optional providers and versions. `py/noxfile.py` is the source of truth for available sessions.
97
+
The SDK uses [nox](https://nox.thea.codes/) for compatibility testing across optional providers and versions. Provider version pins live in `py/pyproject.toml` under `[tool.braintrust.matrix]`; the noxfile reads them at import time. `py/noxfile.py` is the source of truth for available sessions and their auxiliary deps.
99
98
100
99
### VCR Tests
101
100
@@ -187,7 +186,7 @@ To benchmark with the optional `orjson` fast-path installed:
0 commit comments