diff --git a/ddtrace/contrib/internal/anthropic/patch.py b/ddtrace/contrib/internal/anthropic/patch.py index 73731f703a1..1bc40be87a1 100644 --- a/ddtrace/contrib/internal/anthropic/patch.py +++ b/ddtrace/contrib/internal/anthropic/patch.py @@ -118,6 +118,23 @@ def patch() -> None: ) wrap("anthropic", "resources.beta.messages.messages.AsyncMessages.stream", traced_chat_model_generate) + # AnthropicBedrock / AsyncAnthropicBedrock define their own beta Messages classes in + # anthropic.lib.bedrock._beta_messages whose `create` attribute is bound to the first-party + # function at module import time, before patch() runs. The wrap() above on the first-party + # class does not affect those captured references, so Bedrock callers see no spans unless we + # also wrap the Bedrock module paths directly. + try: + import anthropic.lib.bedrock._beta_messages # noqa: F401 + except ImportError: + pass + else: + wrap("anthropic", "lib.bedrock._beta_messages.Messages.create", traced_chat_model_generate) + wrap( + "anthropic", + "lib.bedrock._beta_messages.AsyncMessages.create", + traced_async_chat_model_generate, + ) + def unpatch() -> None: if not getattr(anthropic, "_datadog_patch", False): @@ -136,4 +153,12 @@ def unpatch() -> None: unwrap(anthropic.resources.beta.messages.messages.AsyncMessages, "create") unwrap(anthropic.resources.beta.messages.messages.AsyncMessages, "stream") + try: + import anthropic.lib.bedrock._beta_messages as _bedrock_beta_messages + except ImportError: + pass + else: + unwrap(_bedrock_beta_messages.Messages, "create") + unwrap(_bedrock_beta_messages.AsyncMessages, "create") + delattr(anthropic, "_datadog_integration") diff --git a/releasenotes/notes/fix-anthropic-bedrock-beta-messages-18075-3c8a7e2b1f4d6c9a.yaml b/releasenotes/notes/fix-anthropic-bedrock-beta-messages-18075-3c8a7e2b1f4d6c9a.yaml new file mode 100644 index 00000000000..4b5c96f5d09 --- /dev/null +++ b/releasenotes/notes/fix-anthropic-bedrock-beta-messages-18075-3c8a7e2b1f4d6c9a.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + anthropic: Fixes missing APM and LLM Observability spans for ``AnthropicBedrock`` / ``AsyncAnthropicBedrock`` clients when calling the beta messages API. + ``anthropic.lib.bedrock._beta_messages`` defines its own ``Messages`` / ``AsyncMessages`` classes whose ``create`` attribute is bound to the first-party + function at import time, before the integration's ``patch()`` runs, so wrapping only the first-party class left Bedrock callers untraced.