chore(deps): weekly dependency update - #783
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5cb0ae0ca6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".
openai 3.16.1 converted its resource packages to PEP 562 lazy re-exports. `_resolve_attr_path` walks with `inspect.getattr_static`, which never invokes a module-level `__getattr__`, so `openai.resources.chat.completions.Completions` looked absent and `ChatCompletionsPatcher` silently no-opped: after `setup_openai()` / `auto_instrument()`, chat completions produced no spans at all. Fall back to a plain getattr when the object being walked is a module — modules carry no descriptors, so nothing is triggered that getattr_static was protecting against. Also refresh the `latest` cassettes for the provider SDKs this dependency update bumped by a minor version: openai, anthropic, ai-sdk, litellm, google-genai, openrouter, pydantic-ai, strands, typesafe, pipecat. dspy is refreshed too — its session installs the litellm matrix pin, and litellm 1.102.0 fetches the model price map at runtime, which the old cassettes did not carry. huggingface-hub cassettes are left as-is: re-recording fails because the tests pin `provider="cerebras"` / `provider="featherless-ai"` for models HF no longer routes there. That is pre-existing test drift, not a 1.32.0 regression, and the committed cassettes still play back green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
CI failed test_dspy(latest) on Windows across 3.11-3.14. Two separate problems, both from the LiteLLM 1.100.1 -> 1.102.0 bump. 1.102.0 fetches model_prices_and_context_window.json from GitHub on import. My earlier re-record captured it, which both bloated the cassette by ~3MB and displaced the tiktoken cl100k_base download that CI needs and my machine (warm tiktoken cache) never makes. Setting LITELLM_LOCAL_MODEL_COST_MAP keeps the fetch off the wire entirely, so the cassette goes back to being about the traffic under test -- it is now byte-identical to main again. The env var is scoped to the DSPy session on purpose: an older LiteLLM's bundled map does not know newer model names, and test_litellm(1.74.0) fails provider resolution for gpt-image-1-mini under it. Also make patcher module resolution consult sys.modules before importlib. Separately, test_mistral(latest) failed on ubuntu/3.10 with `KeyError: <thread id>` raised from importlib._bootstrap while resolve_root() imported mistralai.client.chat -- CPython 3.10's re-entrancy bookkeeping tripping over our own lock traffic. We call import_module for every patcher on every setup(), almost always for a module that is already imported, so the sys.modules fast path removes nearly all of it. That failure does not reproduce locally (3/3 green on 3.10), so this is a mitigation rather than a proven cure; it is a worthwhile change on its own merits either way. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 316ed395ff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
| module = sys.modules.get(name) | ||
| if module is not None: | ||
| return module |
There was a problem hiding this comment.
Wait for modules that are still initializing
When setup() races with a provider or provider-submodule import on another thread, the loader has already inserted a partially initialized module into sys.modules, so this fast path returns it before its patch targets exist. The previous importlib.import_module() call waited on the per-module import lock; now patchers can conclude that their targets are absent and leave subsequent provider calls uninstrumented unless setup() is invoked again. Keep the shortcut for fully initialized modules, but fall back to the import machinery when the module spec is still initializing.
Useful? React with 👍 / 👎.
|
|
||
| [tool.braintrust.matrix.claude-agent-sdk] | ||
| latest = "claude-agent-sdk==0.2.152" | ||
| latest = "claude-agent-sdk==0.2.157" |
There was a problem hiding this comment.
Re-record Claude transport cassettes for 0.2.157
The latest Claude Agent SDK session now installs 0.2.157, but py/src/braintrust/integrations/claude_agent_sdk/cassettes/latest/ is unchanged and therefore still replays the prior SDK's subprocess protocol. Fresh evidence after the earlier review is that this revision re-records the HTTP cassettes for several upgraded providers while leaving every Claude transport cassette untouched, so CI cannot detect request/event-shape changes introduced by this upgrade; record and validate the latest Claude cassettes with 0.2.157.
AGENTS.md reference: AGENTS.md:L219-L224
Useful? React with 👍 / 👎.
…#793) Follow-up to #783, which merged before this landed. Addresses the Codex review finding on that PR. ## The problem #783 added a `sys.modules` fast path to `_import_optional_module` so patcher resolution stops reacquiring the import lock on every `setup()`. It returned any module present in `sys.modules`. The loader inserts a module into `sys.modules` **before** executing its body. So when `setup()` races a provider import on another thread, the shortcut hands back a half-built module: its patch targets do not exist yet, `applies()` concludes they are absent, and the patcher is **silently skipped**. `importlib.import_module` would have blocked on the per-module lock until the other thread finished. That is the same failure mode #783 set out to fix for openai's lazy modules, reintroduced in a narrower window — worth closing rather than leaving. ## The fix Guard the shortcut with the spec's `_initializing` flag. This is not an invented heuristic: it is the predicate CPython itself uses for the same decision. From 3.11+ `importlib._bootstrap._find_and_load`: ```python # Optimization: we avoid unneeded module locking if the module # already exists in sys.modules and is fully initialized. module = sys.modules.get(name, _NEEDS_LOADING) if (module is _NEEDS_LOADING or getattr(getattr(module, "__spec__", None), "_initializing", False)): ... ``` ## Why keep the shortcut at all 3.10's `_find_and_load` has no such optimization — it takes the module lock unconditionally: ```python def _find_and_load(name, import_): with _ModuleLockManager(name): ... ``` That unconditional lock is what produced the `KeyError: <thread id>` from `importlib._bootstrap` on the ubuntu/3.10 shard of #783 (3.10's `_blocking_on` is one slot per thread, so a re-entrant import deletes the outer frame's entry). On 3.11+ this shortcut is effectively redundant with CPython's own; on 3.10 it is doing real work. ## Testing Added `test_import_optional_module_waits_for_initializing_module`, which puts a module with `_initializing = True` in `sys.modules` and asserts we fall through to the import machinery, then that the shortcut applies again once initialization completes. `test_core` green on 3.10 (859 passed) and 3.14 (861 passed). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Automated weekly dependency update via
python scripts/update-matrix-latest.py && uv lock --upgrade.