fix(core): Instrument Anthropic client in place instead of via a deep proxy#22305
fix(core): Instrument Anthropic client in place instead of via a deep proxy#22305logaretm wants to merge 1 commit into
Conversation
… proxy The Anthropic integration wrapped the client in a deep Proxy that ran every method with the raw object as `this`. That changed the client's observable semantics: internal delegation (`messages.stream()` calling `this.create()`) resolved against the raw object, so it escaped any outer wrapper and behaved differently than an uninstrumented client. Instrument the registered methods in place instead (own properties shadowing the prototype), invoking them with the caller's `this`. Instrumentation is now observationally transparent: private-field access and internal delegation work as they do on a plain client. A re-entrancy guard keyed on the active streaming helper span keeps `stream()`'s internal `create()` call from producing a duplicate span.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 069d7fb. Configure here.
| */ | ||
| export function instrumentAnthropicAiClient<T extends object>(anthropicAiClient: T, options?: AnthropicAiOptions): T { | ||
| return createDeepProxy(anthropicAiClient, '', resolveAIRecordingOptions(options)); | ||
| return instrumentClientInPlace(anthropicAiClient, resolveAIRecordingOptions(options)); |
There was a problem hiding this comment.
Missing regression test for fix
Medium Severity
Flagged because it was mentioned in the PR review rules file: this is a fix PR, but the diff only changes production code and does not add a unit, integration, or E2E test covering the regression (Proxy-related observable behavior / in-place instrumentation). That coverage should fail without the fix and pass with it.
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 069d7fb. Configure here.
size-limit report 📦
|
nicohrubec
left a comment
There was a problem hiding this comment.
were you able to reproduce the broken behavior? we use the same deep proxy pattern in openai and google genai, if this approach is really inherently broken we should of course change it but we should first ensure that we are actually fixing anything imo. do we know what specifically causes the issues?
|
@nicohrubec Yep, reproduced it with a simulation of what braintrust does. The cause is our deep proxy binds every method to the raw underlying object, so when This kinda allows us to get out of the way while keeping the same capabilities we had. The other two instrumentations don't use |


Instruments the Anthropic client's methods in place instead of wrapping the client in a deep
Proxy, so our instrumentation stops changing the client's observable behavior.closes #20291