paid-python 1.0.3__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {paid_python-1.0.3 → paid_python-1.0.4}/PKG-INFO +1 -1
- {paid_python-1.0.3 → paid_python-1.0.4}/pyproject.toml +1 -1
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/client_wrapper.py +2 -2
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/anthropic_patches/__init__.py +2 -0
- paid_python-1.0.4/src/paid/tracing/anthropic_patches/patches.py +394 -0
- paid_python-1.0.3/src/paid/tracing/anthropic_patches/patches.py +0 -170
- {paid_python-1.0.3 → paid_python-1.0.4}/LICENSE +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/README.md +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/contacts/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/contacts/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/contacts/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/api_error.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/datetime_utils.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/file.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/force_multipart.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_sse/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_sse/_api.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_sse/_decoders.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_sse/_exceptions.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/http_sse/_models.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/jsonable_encoder.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/pydantic_utilities.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/query_encoder.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/remove_none_from_dict.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/request_options.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/core/serialization.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/customers/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/customers/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/customers/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/environment.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/errors/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/errors/bad_request_error.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/errors/forbidden_error.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/errors/internal_server_error.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/errors/not_found_error.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/invoices/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/invoices/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/invoices/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/logger.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/orders/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/orders/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/orders/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/products/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/products/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/products/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/py.typed +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/signals/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/signals/client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/signals/raw_client.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/autoinstrumentation.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/context_data.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/context_manager.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/distributed_tracing.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/signal.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/tracing.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/anthropic/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/anthropic/anthropicWrapper.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/bedrock/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/bedrock/bedrockWrapper.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/gemini/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/gemini/geminiWrapper.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/langchain/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/langchain/paidLangChainCallback.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/mistral/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/mistral/mistralWrapper.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/openai/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/openai/openAiWrapper.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/openai_agents/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/openai_agents/openaiAgentsHook.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/utils.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/__init__.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/attribution.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/bulk_signals_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/contact.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/contact_billing_address.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/contact_list_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_attribution.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_billing_address.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_by_external_id.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_by_id.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_creation_state.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/customer_list_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/empty_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/error_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_line.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_line_payment_status.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_lines_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_list_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_payment_status.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_source.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_status.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/invoice_tax_status.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/order.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/order_creation_state.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/order_line.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/order_lines_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/order_list_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/pagination.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/product.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/product_by_external_id.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/product_by_id.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/product_list_response.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/signal.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/update_contact_request.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/update_customer_request.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/types/update_product_request.py +0 -0
- {paid_python-1.0.3 → paid_python-1.0.4}/src/paid/version.py +0 -0
|
@@ -24,12 +24,12 @@ class BaseClientWrapper:
|
|
|
24
24
|
import platform
|
|
25
25
|
|
|
26
26
|
headers: typing.Dict[str, str] = {
|
|
27
|
-
"User-Agent": "paid-python/1.0.
|
|
27
|
+
"User-Agent": "paid-python/1.0.4",
|
|
28
28
|
"X-Fern-Language": "Python",
|
|
29
29
|
"X-Fern-Runtime": f"python/{platform.python_version()}",
|
|
30
30
|
"X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
|
|
31
31
|
"X-Fern-SDK-Name": "paid-python",
|
|
32
|
-
"X-Fern-SDK-Version": "1.0.
|
|
32
|
+
"X-Fern-SDK-Version": "1.0.4",
|
|
33
33
|
**(self.get_custom_headers() or {}),
|
|
34
34
|
}
|
|
35
35
|
headers["Authorization"] = f"Bearer {self._get_token()}"
|
|
@@ -10,6 +10,7 @@ from .patches import (
|
|
|
10
10
|
_patch_message_stream_manager,
|
|
11
11
|
_patch_stream_context_managers,
|
|
12
12
|
_wrap_async_messages_stream,
|
|
13
|
+
_wrap_beta_messages,
|
|
13
14
|
instrument_anthropic,
|
|
14
15
|
uninstrument_anthropic,
|
|
15
16
|
)
|
|
@@ -20,6 +21,7 @@ __all__ = [
|
|
|
20
21
|
"_patch_stream_context_managers",
|
|
21
22
|
"_patch_message_stream_manager",
|
|
22
23
|
"_wrap_async_messages_stream",
|
|
24
|
+
"_wrap_beta_messages",
|
|
23
25
|
"_AsyncMessageStreamManagerProxy",
|
|
24
26
|
"_original_async_messages_stream",
|
|
25
27
|
]
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"""Monkey-patches for openinference-instrumentation-anthropic."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict
|
|
6
|
+
|
|
7
|
+
from opentelemetry import trace as trace_api
|
|
8
|
+
from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore[import-untyped]
|
|
9
|
+
|
|
10
|
+
from paid.logger import logger
|
|
11
|
+
from paid.tracing import tracing
|
|
12
|
+
|
|
13
|
+
_original_async_messages_stream = None
|
|
14
|
+
|
|
15
|
+
# Originals for the beta path, keyed by method name.
|
|
16
|
+
_beta_originals: Dict[str, Any] = {}
|
|
17
|
+
|
|
18
|
+
_BETA_MODULE = "anthropic.resources.beta.messages.messages"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def instrument_anthropic() -> None:
|
|
22
|
+
"""Apply all Anthropic patches. Call after AnthropicInstrumentor().instrument()."""
|
|
23
|
+
_patch_stream_context_managers()
|
|
24
|
+
_patch_message_stream_manager()
|
|
25
|
+
_wrap_async_messages_stream()
|
|
26
|
+
_patch_response_accumulator_for_beta()
|
|
27
|
+
_wrap_beta_messages()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def uninstrument_anthropic() -> None:
|
|
31
|
+
global _original_async_messages_stream
|
|
32
|
+
if _original_async_messages_stream is not None:
|
|
33
|
+
try:
|
|
34
|
+
from anthropic.resources.messages import AsyncMessages
|
|
35
|
+
AsyncMessages.stream = _original_async_messages_stream # type: ignore[method-assign]
|
|
36
|
+
except Exception:
|
|
37
|
+
pass
|
|
38
|
+
_original_async_messages_stream = None
|
|
39
|
+
|
|
40
|
+
_uninstrument_beta_messages()
|
|
41
|
+
|
|
42
|
+
def _patch_stream_context_managers() -> None:
|
|
43
|
+
try:
|
|
44
|
+
from openinference.instrumentation.anthropic._stream import (
|
|
45
|
+
_MessagesStream,
|
|
46
|
+
_Stream,
|
|
47
|
+
)
|
|
48
|
+
except ImportError:
|
|
49
|
+
logger.debug("Could not import stream classes for patching, skipping")
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
for cls in (_MessagesStream, _Stream):
|
|
53
|
+
if not hasattr(cls, "__aenter__"):
|
|
54
|
+
|
|
55
|
+
async def _aenter(self): # type: ignore[misc]
|
|
56
|
+
if hasattr(self.__wrapped__, "__aenter__"):
|
|
57
|
+
await self.__wrapped__.__aenter__()
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
cls.__aenter__ = _aenter # type: ignore[attr-defined]
|
|
61
|
+
|
|
62
|
+
if not hasattr(cls, "__aexit__"):
|
|
63
|
+
|
|
64
|
+
async def _aexit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
65
|
+
if hasattr(self.__wrapped__, "__aexit__"):
|
|
66
|
+
return await self.__wrapped__.__aexit__(exc_type, exc_val, exc_tb)
|
|
67
|
+
|
|
68
|
+
cls.__aexit__ = _aexit # type: ignore[attr-defined]
|
|
69
|
+
|
|
70
|
+
# Always override: ObjectProxy's defaults return the wrapped object, bypassing instrumentation.
|
|
71
|
+
def _enter(self): # type: ignore[misc]
|
|
72
|
+
if hasattr(self.__wrapped__, "__enter__"):
|
|
73
|
+
self.__wrapped__.__enter__()
|
|
74
|
+
return self
|
|
75
|
+
|
|
76
|
+
cls.__enter__ = _enter # type: ignore[attr-defined]
|
|
77
|
+
|
|
78
|
+
def _exit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
79
|
+
if hasattr(self.__wrapped__, "__exit__"):
|
|
80
|
+
return self.__wrapped__.__exit__(exc_type, exc_val, exc_tb)
|
|
81
|
+
|
|
82
|
+
cls.__exit__ = _exit # type: ignore[attr-defined]
|
|
83
|
+
|
|
84
|
+
logger.debug("Patched stream proxies with context manager support")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Fix 2: _MessageStreamManager.__enter__ calls __api_request() returning a raw stream,
|
|
88
|
+
# losing the high-level MessageStream (.text_stream, .get_final_message()).
|
|
89
|
+
# We delegate to the real __enter__ instead, then wrap in _MessagesStream for tracing.
|
|
90
|
+
|
|
91
|
+
def _patch_message_stream_manager() -> None:
|
|
92
|
+
try:
|
|
93
|
+
from openinference.instrumentation.anthropic._stream import _MessagesStream
|
|
94
|
+
from openinference.instrumentation.anthropic._wrappers import _MessageStreamManager
|
|
95
|
+
except ImportError:
|
|
96
|
+
logger.debug("Could not import _MessageStreamManager for patching, skipping")
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
def _fixed_enter(self): # type: ignore[misc]
|
|
100
|
+
message_stream = self.__wrapped__.__enter__()
|
|
101
|
+
return _MessagesStream(message_stream, self._self_with_span)
|
|
102
|
+
|
|
103
|
+
def _fixed_exit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
104
|
+
try:
|
|
105
|
+
return self.__wrapped__.__exit__(exc_type, exc_val, exc_tb)
|
|
106
|
+
finally:
|
|
107
|
+
self._self_with_span.finish_tracing() # idempotent
|
|
108
|
+
|
|
109
|
+
_MessageStreamManager.__enter__ = _fixed_enter # type: ignore[attr-defined, method-assign]
|
|
110
|
+
_MessageStreamManager.__exit__ = _fixed_exit # type: ignore[attr-defined, method-assign]
|
|
111
|
+
|
|
112
|
+
logger.debug("Patched _MessageStreamManager with fixed __enter__/__exit__")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Fix 3: openinference only wraps sync Messages.stream, not AsyncMessages.stream.
|
|
116
|
+
|
|
117
|
+
class _AsyncMessageStreamManagerProxy(ObjectProxy): # type: ignore[misc]
|
|
118
|
+
"""Wraps AsyncMessageStreamManager with span lifecycle management."""
|
|
119
|
+
|
|
120
|
+
def __init__(self, manager: Any, span: trace_api.Span) -> None:
|
|
121
|
+
super().__init__(manager)
|
|
122
|
+
self._self_span = span
|
|
123
|
+
|
|
124
|
+
async def __aenter__(self): # type: ignore[misc]
|
|
125
|
+
return await self.__wrapped__.__aenter__()
|
|
126
|
+
|
|
127
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
128
|
+
try:
|
|
129
|
+
return await self.__wrapped__.__aexit__(exc_type, exc_val, exc_tb)
|
|
130
|
+
finally:
|
|
131
|
+
try:
|
|
132
|
+
if exc_type:
|
|
133
|
+
self._self_span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, str(exc_val)))
|
|
134
|
+
else:
|
|
135
|
+
self._self_span.set_status(trace_api.StatusCode.OK)
|
|
136
|
+
self._self_span.end()
|
|
137
|
+
except Exception:
|
|
138
|
+
logger.debug("Failed to end span for AsyncMessages.stream", exc_info=True)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _wrap_async_messages_stream() -> None:
|
|
142
|
+
global _original_async_messages_stream
|
|
143
|
+
try:
|
|
144
|
+
from anthropic.resources.messages import AsyncMessages
|
|
145
|
+
except ImportError:
|
|
146
|
+
logger.debug("Could not import AsyncMessages, skipping async stream wrapping")
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
_original_async_messages_stream = AsyncMessages.stream # type: ignore[assignment]
|
|
150
|
+
|
|
151
|
+
def _wrapper(wrapped, instance, args, kwargs): # type: ignore[misc]
|
|
152
|
+
tracer = tracing.paid_tracer_provider.get_tracer("paid.anthropic")
|
|
153
|
+
span = tracer.start_span(name="AsyncMessagesStream", record_exception=False, set_status_on_exception=False)
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
if kwargs.get("model"):
|
|
157
|
+
span.set_attribute("llm.model_name", str(kwargs["model"]))
|
|
158
|
+
span.set_attribute("openinference.span.kind", "LLM")
|
|
159
|
+
span.set_attribute("llm.provider", "anthropic")
|
|
160
|
+
span.set_attribute("llm.system", "anthropic")
|
|
161
|
+
except Exception:
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
try:
|
|
165
|
+
response = wrapped(*args, **kwargs)
|
|
166
|
+
except Exception as exc:
|
|
167
|
+
span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, str(exc)))
|
|
168
|
+
span.record_exception(exc)
|
|
169
|
+
span.end()
|
|
170
|
+
raise
|
|
171
|
+
|
|
172
|
+
return _AsyncMessageStreamManagerProxy(response, span)
|
|
173
|
+
|
|
174
|
+
wrap_function_wrapper(module="anthropic.resources.messages", name="AsyncMessages.stream", wrapper=_wrapper)
|
|
175
|
+
logger.debug("Wrapped AsyncMessages.stream for instrumentation")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _patch_response_accumulator_for_beta() -> None:
|
|
181
|
+
"""Extend _MessageResponseAccumulator.process_chunk to handle beta event types."""
|
|
182
|
+
try:
|
|
183
|
+
from openinference.instrumentation.anthropic._stream import _MessageResponseAccumulator
|
|
184
|
+
except ImportError:
|
|
185
|
+
logger.debug("Could not import _MessageResponseAccumulator, skipping beta accumulator patch")
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
from anthropic.types.beta import (
|
|
190
|
+
BetaRawContentBlockDeltaEvent,
|
|
191
|
+
BetaRawContentBlockStartEvent,
|
|
192
|
+
BetaRawMessageDeltaEvent,
|
|
193
|
+
BetaRawMessageStartEvent,
|
|
194
|
+
)
|
|
195
|
+
except ImportError:
|
|
196
|
+
logger.debug("Could not import beta event types, skipping beta accumulator patch")
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
_original_process_chunk = _MessageResponseAccumulator.process_chunk
|
|
200
|
+
|
|
201
|
+
def _process_chunk_with_beta(self, chunk): # type: ignore[misc]
|
|
202
|
+
"""Handles both regular and beta event types."""
|
|
203
|
+
if isinstance(chunk, BetaRawMessageStartEvent):
|
|
204
|
+
self._is_null = False
|
|
205
|
+
self._current_message_idx += 1
|
|
206
|
+
value = {
|
|
207
|
+
"messages": {
|
|
208
|
+
"index": str(self._current_message_idx),
|
|
209
|
+
"role": chunk.message.role,
|
|
210
|
+
"input_tokens": str(chunk.message.usage.input_tokens),
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
self._values += value
|
|
214
|
+
elif isinstance(chunk, BetaRawContentBlockStartEvent):
|
|
215
|
+
self._is_null = False
|
|
216
|
+
self._current_content_block_type = chunk.content_block
|
|
217
|
+
elif isinstance(chunk, BetaRawContentBlockDeltaEvent):
|
|
218
|
+
self._is_null = False
|
|
219
|
+
# Duck-type check: BetaTextBlock/BetaToolUseBlock have the same .type attribute
|
|
220
|
+
block_type = getattr(self._current_content_block_type, "type", None)
|
|
221
|
+
if block_type == "text":
|
|
222
|
+
value = {
|
|
223
|
+
"messages": {
|
|
224
|
+
"index": str(self._current_message_idx),
|
|
225
|
+
"content": {
|
|
226
|
+
"index": chunk.index,
|
|
227
|
+
"type": block_type,
|
|
228
|
+
"text": chunk.delta.text, # type: ignore[union-attr]
|
|
229
|
+
},
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
self._values += value
|
|
233
|
+
elif block_type == "tool_use":
|
|
234
|
+
value = {
|
|
235
|
+
"messages": {
|
|
236
|
+
"index": str(self._current_message_idx),
|
|
237
|
+
"content": {
|
|
238
|
+
"index": chunk.index,
|
|
239
|
+
"type": block_type,
|
|
240
|
+
"tool_name": self._current_content_block_type.name,
|
|
241
|
+
"tool_input": chunk.delta.partial_json, # type: ignore[union-attr]
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
self._values += value
|
|
246
|
+
elif isinstance(chunk, BetaRawMessageDeltaEvent):
|
|
247
|
+
self._is_null = False
|
|
248
|
+
value = {
|
|
249
|
+
"messages": {
|
|
250
|
+
"index": str(self._current_message_idx),
|
|
251
|
+
"stop_reason": chunk.delta.stop_reason,
|
|
252
|
+
"output_tokens": str(chunk.usage.output_tokens),
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
self._values += value
|
|
256
|
+
else:
|
|
257
|
+
# Non-beta event — delegate to the original.
|
|
258
|
+
return _original_process_chunk(self, chunk)
|
|
259
|
+
|
|
260
|
+
_MessageResponseAccumulator.process_chunk = _process_chunk_with_beta # type: ignore[method-assign]
|
|
261
|
+
logger.debug("Patched _MessageResponseAccumulator.process_chunk for beta event types")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# ---------------------------------------------------------------------------
|
|
265
|
+
# We reuse the same openinference wrapper classes (_MessagesWrapper,
|
|
266
|
+
# _AsyncMessagesWrapper, _MessagesStreamWrapper) targeting the beta module.
|
|
267
|
+
# For AsyncMessages.stream we use the same custom approach as Fix 3 since
|
|
268
|
+
# openinference has no async stream wrapper.
|
|
269
|
+
# ---------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _wrap_beta_messages() -> None:
|
|
273
|
+
"""Wrap the beta Messages/AsyncMessages.create and .stream methods."""
|
|
274
|
+
try:
|
|
275
|
+
from anthropic.resources.beta.messages.messages import (
|
|
276
|
+
AsyncMessages as BetaAsyncMessages,
|
|
277
|
+
)
|
|
278
|
+
from anthropic.resources.beta.messages.messages import (
|
|
279
|
+
Messages as BetaMessages,
|
|
280
|
+
)
|
|
281
|
+
except ImportError:
|
|
282
|
+
logger.debug("Could not import beta Messages classes, skipping beta wrapping")
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
try:
|
|
286
|
+
from openinference.instrumentation import OITracer, TraceConfig
|
|
287
|
+
from openinference.instrumentation.anthropic._wrappers import (
|
|
288
|
+
_AsyncMessagesWrapper,
|
|
289
|
+
_MessagesStreamWrapper,
|
|
290
|
+
_MessagesWrapper,
|
|
291
|
+
)
|
|
292
|
+
except ImportError:
|
|
293
|
+
logger.debug("Could not import openinference wrappers, skipping beta wrapping")
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
tracer: trace_api.Tracer = OITracer(
|
|
297
|
+
tracing.paid_tracer_provider.get_tracer(__name__),
|
|
298
|
+
config=TraceConfig(),
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
# --- beta Messages.create (sync) ---
|
|
302
|
+
_beta_originals["Messages.create"] = BetaMessages.create
|
|
303
|
+
wrap_function_wrapper(
|
|
304
|
+
module=_BETA_MODULE,
|
|
305
|
+
name="Messages.create",
|
|
306
|
+
wrapper=_MessagesWrapper(tracer=tracer),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# --- beta AsyncMessages.create (async — primary path for pydantic-ai) ---
|
|
310
|
+
_beta_originals["AsyncMessages.create"] = BetaAsyncMessages.create
|
|
311
|
+
wrap_function_wrapper(
|
|
312
|
+
module=_BETA_MODULE,
|
|
313
|
+
name="AsyncMessages.create",
|
|
314
|
+
wrapper=_AsyncMessagesWrapper(tracer=tracer),
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# --- beta Messages.stream (sync) ---
|
|
318
|
+
_beta_originals["Messages.stream"] = BetaMessages.stream
|
|
319
|
+
wrap_function_wrapper(
|
|
320
|
+
module=_BETA_MODULE,
|
|
321
|
+
name="Messages.stream",
|
|
322
|
+
wrapper=_MessagesStreamWrapper(tracer=tracer),
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# --- beta AsyncMessages.stream (async) ---
|
|
326
|
+
_beta_originals["AsyncMessages.stream"] = BetaAsyncMessages.stream # type: ignore[assignment]
|
|
327
|
+
|
|
328
|
+
def _beta_async_stream_wrapper(wrapped, instance, args, kwargs): # type: ignore[misc]
|
|
329
|
+
beta_tracer = tracing.paid_tracer_provider.get_tracer("paid.anthropic")
|
|
330
|
+
span = beta_tracer.start_span(
|
|
331
|
+
name="AsyncMessagesStream", record_exception=False, set_status_on_exception=False
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
try:
|
|
335
|
+
if kwargs.get("model"):
|
|
336
|
+
span.set_attribute("llm.model_name", str(kwargs["model"]))
|
|
337
|
+
span.set_attribute("openinference.span.kind", "LLM")
|
|
338
|
+
span.set_attribute("llm.provider", "anthropic")
|
|
339
|
+
span.set_attribute("llm.system", "anthropic")
|
|
340
|
+
except Exception:
|
|
341
|
+
pass
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
response = wrapped(*args, **kwargs)
|
|
345
|
+
except Exception as exc:
|
|
346
|
+
span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, str(exc)))
|
|
347
|
+
span.record_exception(exc)
|
|
348
|
+
span.end()
|
|
349
|
+
raise
|
|
350
|
+
|
|
351
|
+
return _AsyncMessageStreamManagerProxy(response, span)
|
|
352
|
+
|
|
353
|
+
wrap_function_wrapper(
|
|
354
|
+
module=_BETA_MODULE,
|
|
355
|
+
name="AsyncMessages.stream",
|
|
356
|
+
wrapper=_beta_async_stream_wrapper,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
logger.debug("Wrapped beta Messages/AsyncMessages.create and .stream for instrumentation")
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _uninstrument_beta_messages() -> None:
|
|
363
|
+
"""Restore original beta Messages/AsyncMessages methods."""
|
|
364
|
+
if not _beta_originals:
|
|
365
|
+
return
|
|
366
|
+
|
|
367
|
+
try:
|
|
368
|
+
from anthropic.resources.beta.messages.messages import (
|
|
369
|
+
AsyncMessages as BetaAsyncMessages,
|
|
370
|
+
)
|
|
371
|
+
from anthropic.resources.beta.messages.messages import (
|
|
372
|
+
Messages as BetaMessages,
|
|
373
|
+
)
|
|
374
|
+
except ImportError:
|
|
375
|
+
_beta_originals.clear()
|
|
376
|
+
return
|
|
377
|
+
|
|
378
|
+
_restore = {
|
|
379
|
+
"Messages.create": (BetaMessages, "create"),
|
|
380
|
+
"Messages.stream": (BetaMessages, "stream"),
|
|
381
|
+
"AsyncMessages.create": (BetaAsyncMessages, "create"),
|
|
382
|
+
"AsyncMessages.stream": (BetaAsyncMessages, "stream"),
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
for key, (cls, attr) in _restore.items():
|
|
386
|
+
original = _beta_originals.pop(key, None)
|
|
387
|
+
if original is not None:
|
|
388
|
+
try:
|
|
389
|
+
setattr(cls, attr, original)
|
|
390
|
+
except Exception:
|
|
391
|
+
logger.debug("Failed to restore beta %s", key, exc_info=True)
|
|
392
|
+
|
|
393
|
+
_beta_originals.clear()
|
|
394
|
+
logger.debug("Restored beta Messages/AsyncMessages originals")
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
"""Monkey-patches for openinference-instrumentation-anthropic."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
from opentelemetry import trace as trace_api
|
|
8
|
-
from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore[import-untyped]
|
|
9
|
-
|
|
10
|
-
from paid.logger import logger
|
|
11
|
-
from paid.tracing import tracing
|
|
12
|
-
|
|
13
|
-
_original_async_messages_stream = None
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def instrument_anthropic() -> None:
|
|
17
|
-
"""Apply all Anthropic patches. Call after AnthropicInstrumentor().instrument()."""
|
|
18
|
-
_patch_stream_context_managers()
|
|
19
|
-
_patch_message_stream_manager()
|
|
20
|
-
_wrap_async_messages_stream()
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def uninstrument_anthropic() -> None:
|
|
24
|
-
global _original_async_messages_stream
|
|
25
|
-
if _original_async_messages_stream is not None:
|
|
26
|
-
try:
|
|
27
|
-
from anthropic.resources.messages import AsyncMessages
|
|
28
|
-
AsyncMessages.stream = _original_async_messages_stream # type: ignore[method-assign]
|
|
29
|
-
except Exception:
|
|
30
|
-
pass
|
|
31
|
-
_original_async_messages_stream = None
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Fix 1: _MessagesStream/_Stream — missing context-manager protocol.
|
|
35
|
-
# Python resolves dunders on the class, not the instance, so ObjectProxy.__getattr__ doesn't help.
|
|
36
|
-
|
|
37
|
-
def _patch_stream_context_managers() -> None:
|
|
38
|
-
try:
|
|
39
|
-
from openinference.instrumentation.anthropic._stream import (
|
|
40
|
-
_MessagesStream,
|
|
41
|
-
_Stream,
|
|
42
|
-
)
|
|
43
|
-
except ImportError:
|
|
44
|
-
logger.debug("Could not import stream classes for patching, skipping")
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
for cls in (_MessagesStream, _Stream):
|
|
48
|
-
if not hasattr(cls, "__aenter__"):
|
|
49
|
-
|
|
50
|
-
async def _aenter(self): # type: ignore[misc]
|
|
51
|
-
if hasattr(self.__wrapped__, "__aenter__"):
|
|
52
|
-
await self.__wrapped__.__aenter__()
|
|
53
|
-
return self
|
|
54
|
-
|
|
55
|
-
cls.__aenter__ = _aenter # type: ignore[attr-defined]
|
|
56
|
-
|
|
57
|
-
if not hasattr(cls, "__aexit__"):
|
|
58
|
-
|
|
59
|
-
async def _aexit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
60
|
-
if hasattr(self.__wrapped__, "__aexit__"):
|
|
61
|
-
return await self.__wrapped__.__aexit__(exc_type, exc_val, exc_tb)
|
|
62
|
-
|
|
63
|
-
cls.__aexit__ = _aexit # type: ignore[attr-defined]
|
|
64
|
-
|
|
65
|
-
# Always override: ObjectProxy's defaults return the wrapped object, bypassing instrumentation.
|
|
66
|
-
def _enter(self): # type: ignore[misc]
|
|
67
|
-
if hasattr(self.__wrapped__, "__enter__"):
|
|
68
|
-
self.__wrapped__.__enter__()
|
|
69
|
-
return self
|
|
70
|
-
|
|
71
|
-
cls.__enter__ = _enter # type: ignore[attr-defined]
|
|
72
|
-
|
|
73
|
-
def _exit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
74
|
-
if hasattr(self.__wrapped__, "__exit__"):
|
|
75
|
-
return self.__wrapped__.__exit__(exc_type, exc_val, exc_tb)
|
|
76
|
-
|
|
77
|
-
cls.__exit__ = _exit # type: ignore[attr-defined]
|
|
78
|
-
|
|
79
|
-
logger.debug("Patched stream proxies with context manager support")
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# Fix 2: _MessageStreamManager.__enter__ calls __api_request() returning a raw stream,
|
|
83
|
-
# losing the high-level MessageStream (.text_stream, .get_final_message()).
|
|
84
|
-
# We delegate to the real __enter__ instead, then wrap in _MessagesStream for tracing.
|
|
85
|
-
|
|
86
|
-
def _patch_message_stream_manager() -> None:
|
|
87
|
-
try:
|
|
88
|
-
from openinference.instrumentation.anthropic._stream import _MessagesStream
|
|
89
|
-
from openinference.instrumentation.anthropic._wrappers import _MessageStreamManager
|
|
90
|
-
except ImportError:
|
|
91
|
-
logger.debug("Could not import _MessageStreamManager for patching, skipping")
|
|
92
|
-
return
|
|
93
|
-
|
|
94
|
-
def _fixed_enter(self): # type: ignore[misc]
|
|
95
|
-
message_stream = self.__wrapped__.__enter__()
|
|
96
|
-
return _MessagesStream(message_stream, self._self_with_span)
|
|
97
|
-
|
|
98
|
-
def _fixed_exit(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
99
|
-
try:
|
|
100
|
-
return self.__wrapped__.__exit__(exc_type, exc_val, exc_tb)
|
|
101
|
-
finally:
|
|
102
|
-
self._self_with_span.finish_tracing() # idempotent
|
|
103
|
-
|
|
104
|
-
_MessageStreamManager.__enter__ = _fixed_enter # type: ignore[attr-defined, method-assign]
|
|
105
|
-
_MessageStreamManager.__exit__ = _fixed_exit # type: ignore[attr-defined, method-assign]
|
|
106
|
-
|
|
107
|
-
logger.debug("Patched _MessageStreamManager with fixed __enter__/__exit__")
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
# Fix 3: openinference only wraps sync Messages.stream, not AsyncMessages.stream.
|
|
111
|
-
|
|
112
|
-
class _AsyncMessageStreamManagerProxy(ObjectProxy): # type: ignore[misc]
|
|
113
|
-
"""Wraps AsyncMessageStreamManager with span lifecycle management."""
|
|
114
|
-
|
|
115
|
-
def __init__(self, manager: Any, span: trace_api.Span) -> None:
|
|
116
|
-
super().__init__(manager)
|
|
117
|
-
self._self_span = span
|
|
118
|
-
|
|
119
|
-
async def __aenter__(self): # type: ignore[misc]
|
|
120
|
-
return await self.__wrapped__.__aenter__()
|
|
121
|
-
|
|
122
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb): # type: ignore[misc]
|
|
123
|
-
try:
|
|
124
|
-
return await self.__wrapped__.__aexit__(exc_type, exc_val, exc_tb)
|
|
125
|
-
finally:
|
|
126
|
-
try:
|
|
127
|
-
if exc_type:
|
|
128
|
-
self._self_span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, str(exc_val)))
|
|
129
|
-
else:
|
|
130
|
-
self._self_span.set_status(trace_api.StatusCode.OK)
|
|
131
|
-
self._self_span.end()
|
|
132
|
-
except Exception:
|
|
133
|
-
logger.debug("Failed to end span for AsyncMessages.stream", exc_info=True)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def _wrap_async_messages_stream() -> None:
|
|
137
|
-
global _original_async_messages_stream
|
|
138
|
-
try:
|
|
139
|
-
from anthropic.resources.messages import AsyncMessages
|
|
140
|
-
except ImportError:
|
|
141
|
-
logger.debug("Could not import AsyncMessages, skipping async stream wrapping")
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
_original_async_messages_stream = AsyncMessages.stream # type: ignore[assignment]
|
|
145
|
-
|
|
146
|
-
def _wrapper(wrapped, instance, args, kwargs): # type: ignore[misc]
|
|
147
|
-
tracer = tracing.paid_tracer_provider.get_tracer("paid.anthropic")
|
|
148
|
-
span = tracer.start_span(name="AsyncMessagesStream", record_exception=False, set_status_on_exception=False)
|
|
149
|
-
|
|
150
|
-
try:
|
|
151
|
-
if kwargs.get("model"):
|
|
152
|
-
span.set_attribute("llm.model_name", str(kwargs["model"]))
|
|
153
|
-
span.set_attribute("openinference.span.kind", "LLM")
|
|
154
|
-
span.set_attribute("llm.provider", "anthropic")
|
|
155
|
-
span.set_attribute("llm.system", "anthropic")
|
|
156
|
-
except Exception:
|
|
157
|
-
pass
|
|
158
|
-
|
|
159
|
-
try:
|
|
160
|
-
response = wrapped(*args, **kwargs)
|
|
161
|
-
except Exception as exc:
|
|
162
|
-
span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, str(exc)))
|
|
163
|
-
span.record_exception(exc)
|
|
164
|
-
span.end()
|
|
165
|
-
raise
|
|
166
|
-
|
|
167
|
-
return _AsyncMessageStreamManagerProxy(response, span)
|
|
168
|
-
|
|
169
|
-
wrap_function_wrapper(module="anthropic.resources.messages", name="AsyncMessages.stream", wrapper=_wrapper)
|
|
170
|
-
logger.debug("Wrapped AsyncMessages.stream for instrumentation")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/anthropic/anthropicWrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/langchain/paidLangChainCallback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{paid_python-1.0.3 → paid_python-1.0.4}/src/paid/tracing/wrappers/openai_agents/openaiAgentsHook.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|