a714ff9823
`_store_cached_client()` refuses an `_AuxProbeClientStub`, but `_get_cached_client()` assigns to `_client_cache` directly and so never reaches that guard. check_fns resolve through this path inside `aux_probe_mode()` during tool-schema assembly, and the cache key carries no probe/runtime distinction — so the stored stub is returned to the next real caller sharing that key, which dies on attribute access with `_AuxProbeClientStub used as a real client (attribute 'chat')`. The `async_mode` field in the cache key is what kept this latent: the probe caches the sync variant, so async consumers (`analyze_image`) miss the entry and build a real client, while sync consumers (`browser_vision`) hit the poisoned one and fail on every call. Observed against a local OpenAI-compatible vision endpoint, where `browser_vision` failed every call with that RuntimeError while `analyze_image` against the same provider worked. Guard the inline store the same way `_store_cached_client()` does, and return the stub to the probe caller without caching it. The existing `test_probe_stub_never_cached` pins the invariant only on `_store_cached_client()`, which is why the unguarded door went unnoticed; the new test exercises `_get_cached_client()` and fails without this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>