langtrace-python-sdk 3.8.15__py3-none-any.whl → 3.8.17__py3-none-any.whl
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.
- langtrace_python_sdk/constants/instrumentation/anthropic.py +4 -0
- langtrace_python_sdk/instrumentation/anthropic/instrumentation.py +7 -1
- langtrace_python_sdk/instrumentation/anthropic/patch.py +151 -4
- langtrace_python_sdk/version.py +1 -1
- {langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/METADATA +1 -1
- {langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/RECORD +9 -9
- {langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/WHEEL +0 -0
- {langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/entry_points.txt +0 -0
- {langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -23,7 +23,7 @@ from opentelemetry.trace import TracerProvider
|
|
23
23
|
from opentelemetry.trace import get_tracer
|
24
24
|
from wrapt import wrap_function_wrapper
|
25
25
|
from typing import Any
|
26
|
-
from langtrace_python_sdk.instrumentation.anthropic.patch import messages_create
|
26
|
+
from langtrace_python_sdk.instrumentation.anthropic.patch import messages_create, messages_stream
|
27
27
|
|
28
28
|
logging.basicConfig(level=logging.FATAL)
|
29
29
|
|
@@ -46,6 +46,12 @@ class AnthropicInstrumentation(BaseInstrumentor): # type: ignore[misc]
|
|
46
46
|
"Messages.create",
|
47
47
|
messages_create(version, tracer),
|
48
48
|
)
|
49
|
+
|
50
|
+
wrap_function_wrapper(
|
51
|
+
"anthropic.resources.messages",
|
52
|
+
"Messages.stream",
|
53
|
+
messages_stream(version, tracer),
|
54
|
+
)
|
49
55
|
|
50
56
|
def _instrument_module(self, module_name: str) -> None:
|
51
57
|
pass
|
@@ -56,9 +56,7 @@ def messages_create(version: str, tracer: Tracer) -> Callable[..., Any]:
|
|
56
56
|
prompts = kwargs.get("messages", [])
|
57
57
|
system = kwargs.get("system")
|
58
58
|
if system:
|
59
|
-
prompts
|
60
|
-
"messages", []
|
61
|
-
)
|
59
|
+
prompts.append({"role": "system", "content": system})
|
62
60
|
span_attributes = {
|
63
61
|
**get_langtrace_attributes(version, service_provider),
|
64
62
|
**get_llm_request_attributes(kwargs, prompts=prompts),
|
@@ -72,7 +70,14 @@ def messages_create(version: str, tracer: Tracer) -> Callable[..., Any]:
|
|
72
70
|
span = tracer.start_span(
|
73
71
|
name=get_span_name(APIS["MESSAGES_CREATE"]["METHOD"]), kind=SpanKind.CLIENT
|
74
72
|
)
|
73
|
+
|
75
74
|
set_span_attributes(span, attributes)
|
75
|
+
|
76
|
+
tools = []
|
77
|
+
if kwargs.get("tools") is not None and kwargs.get("tools"):
|
78
|
+
tools.append(json.dumps(kwargs.get("tools")))
|
79
|
+
set_span_attribute(span, SpanAttributes.LLM_TOOLS, json.dumps(tools))
|
80
|
+
|
76
81
|
try:
|
77
82
|
# Attempt to call the original method
|
78
83
|
result = wrapped(*args, **kwargs)
|
@@ -127,7 +132,149 @@ def messages_create(version: str, tracer: Tracer) -> Callable[..., Any]:
|
|
127
132
|
span.end()
|
128
133
|
return result
|
129
134
|
else:
|
130
|
-
return StreamWrapper(result, span)
|
135
|
+
return StreamWrapper(result, span, tool_calls=True)
|
131
136
|
|
132
137
|
# return the wrapped method
|
133
138
|
return traced_method
|
139
|
+
|
140
|
+
|
141
|
+
def messages_stream(version: str, tracer: Tracer) -> Callable[..., Any]:
|
142
|
+
|
143
|
+
def traced_method(
|
144
|
+
wrapped: Callable[..., Any],
|
145
|
+
instance: Any,
|
146
|
+
args: List[Any],
|
147
|
+
kwargs: MessagesCreateKwargs,
|
148
|
+
) -> Any:
|
149
|
+
service_provider = SERVICE_PROVIDERS["ANTHROPIC"]
|
150
|
+
|
151
|
+
prompts = kwargs.get("messages", [])
|
152
|
+
system = kwargs.get("system")
|
153
|
+
if system:
|
154
|
+
prompts.append({"role": "assistant", "content": system})
|
155
|
+
span_attributes = {
|
156
|
+
**get_langtrace_attributes(version, service_provider),
|
157
|
+
**get_llm_request_attributes(kwargs, prompts=prompts),
|
158
|
+
**get_llm_url(instance),
|
159
|
+
SpanAttributes.LLM_PATH: APIS["MESSAGES_STREAM"]["ENDPOINT"],
|
160
|
+
**get_extra_attributes(),
|
161
|
+
}
|
162
|
+
|
163
|
+
attributes = LLMSpanAttributes(**span_attributes)
|
164
|
+
|
165
|
+
span = tracer.start_span(
|
166
|
+
name=get_span_name(APIS["MESSAGES_STREAM"]["METHOD"]), kind=SpanKind.CLIENT
|
167
|
+
)
|
168
|
+
|
169
|
+
set_span_attributes(span, attributes)
|
170
|
+
|
171
|
+
tools = []
|
172
|
+
if kwargs.get("tools") is not None:
|
173
|
+
tools.append(json.dumps(kwargs.get("tools")))
|
174
|
+
set_span_attribute(span, SpanAttributes.LLM_TOOLS, json.dumps(tools))
|
175
|
+
|
176
|
+
try:
|
177
|
+
# Create the original message stream manager
|
178
|
+
original_stream_manager = wrapped(*args, **kwargs)
|
179
|
+
|
180
|
+
# Create a new stream manager that will instrument the stream
|
181
|
+
# while preserving the stream
|
182
|
+
class InstrumentedMessageStreamManager:
|
183
|
+
def __init__(self, original_manager, span):
|
184
|
+
self.original_manager = original_manager
|
185
|
+
self.span = span
|
186
|
+
|
187
|
+
def __enter__(self):
|
188
|
+
# Enter the original context manager to get the stream
|
189
|
+
original_stream = self.original_manager.__enter__()
|
190
|
+
|
191
|
+
# Create a wrapper iterator
|
192
|
+
class InstrumentedStream:
|
193
|
+
def __init__(self, original_stream, span):
|
194
|
+
self.original_stream = original_stream
|
195
|
+
self.span = span
|
196
|
+
self.message_stop_processed = False
|
197
|
+
|
198
|
+
def __iter__(self):
|
199
|
+
return self
|
200
|
+
|
201
|
+
def __next__(self):
|
202
|
+
try:
|
203
|
+
chunk = next(self.original_stream)
|
204
|
+
|
205
|
+
# Apply instrumentation only once on message_stop
|
206
|
+
if chunk.type == "message_stop" and not self.message_stop_processed:
|
207
|
+
self.message_stop_processed = True
|
208
|
+
response_message = chunk.message
|
209
|
+
|
210
|
+
responses = [
|
211
|
+
{
|
212
|
+
"role": (
|
213
|
+
response_message.role
|
214
|
+
if response_message.role
|
215
|
+
else "assistant"
|
216
|
+
),
|
217
|
+
"content": message.text,
|
218
|
+
}
|
219
|
+
for message in response_message.content if message.type == "text"
|
220
|
+
]
|
221
|
+
|
222
|
+
set_event_completion(self.span, responses)
|
223
|
+
|
224
|
+
if hasattr(response_message, "usage") and response_message.usage is not None:
|
225
|
+
set_span_attribute(
|
226
|
+
self.span,
|
227
|
+
SpanAttributes.LLM_USAGE_PROMPT_TOKENS,
|
228
|
+
response_message.usage.input_tokens,
|
229
|
+
)
|
230
|
+
set_span_attribute(
|
231
|
+
self.span,
|
232
|
+
SpanAttributes.LLM_USAGE_COMPLETION_TOKENS,
|
233
|
+
response_message.usage.output_tokens,
|
234
|
+
)
|
235
|
+
set_span_attribute(
|
236
|
+
self.span,
|
237
|
+
SpanAttributes.LLM_USAGE_TOTAL_TOKENS,
|
238
|
+
response_message.usage.input_tokens + response_message.usage.output_tokens,
|
239
|
+
)
|
240
|
+
|
241
|
+
# Forward the chunk
|
242
|
+
return chunk
|
243
|
+
except StopIteration:
|
244
|
+
# End the span when we're done with the stream
|
245
|
+
self.span.end()
|
246
|
+
raise
|
247
|
+
except Exception as err:
|
248
|
+
self.span.record_exception(err)
|
249
|
+
self.span.set_status(StatusCode.ERROR, str(err))
|
250
|
+
self.span.end()
|
251
|
+
raise
|
252
|
+
|
253
|
+
def close(self):
|
254
|
+
self.original_stream.close()
|
255
|
+
if not self.message_stop_processed:
|
256
|
+
self.span.end()
|
257
|
+
|
258
|
+
# Return our instrumented stream wrapper
|
259
|
+
return InstrumentedStream(original_stream, self.span)
|
260
|
+
|
261
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
262
|
+
result = self.original_manager.__exit__(exc_type, exc_val, exc_tb)
|
263
|
+
|
264
|
+
if exc_type is not None:
|
265
|
+
self.span.record_exception(exc_val)
|
266
|
+
self.span.set_status(StatusCode.ERROR, str(exc_val))
|
267
|
+
self.span.end()
|
268
|
+
|
269
|
+
return result
|
270
|
+
|
271
|
+
# Return the instrumented stream manager
|
272
|
+
return InstrumentedMessageStreamManager(original_stream_manager, span)
|
273
|
+
|
274
|
+
except Exception as err:
|
275
|
+
span.record_exception(err)
|
276
|
+
span.set_status(StatusCode.ERROR, str(err))
|
277
|
+
span.end()
|
278
|
+
raise
|
279
|
+
|
280
|
+
return traced_method
|
langtrace_python_sdk/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "3.8.
|
1
|
+
__version__ = "3.8.17"
|
@@ -121,11 +121,11 @@ examples/weaviate_example/__init__.py,sha256=8JMDBsRSEV10HfTd-YC7xb4txBjD3la56sn
|
|
121
121
|
examples/weaviate_example/query_text.py,sha256=wPHQTc_58kPoKTZMygVjTj-2ZcdrIuaausJfMxNQnQc,127162
|
122
122
|
langtrace_python_sdk/__init__.py,sha256=VZM6i71NR7pBQK6XvJWRelknuTYUhqwqE7PlicKa5Wg,1166
|
123
123
|
langtrace_python_sdk/langtrace.py,sha256=JYBCbklWv463lzRUH7pfkHAVoc3YHh-q_2Iv6LZ2HhU,14896
|
124
|
-
langtrace_python_sdk/version.py,sha256=
|
124
|
+
langtrace_python_sdk/version.py,sha256=csVUBgURmjY_-YGxUIC12qiRsv-dOi-b_wDRDkd1SUg,23
|
125
125
|
langtrace_python_sdk/constants/__init__.py,sha256=3CNYkWMdd1DrkGqzLUgNZXjdAlM6UFMlf_F-odAToyc,146
|
126
126
|
langtrace_python_sdk/constants/exporter/langtrace_exporter.py,sha256=EVCrouYCpY98f0KSaKr4PzNxPULTZZO6dSA_crEOyJU,106
|
127
127
|
langtrace_python_sdk/constants/instrumentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
128
|
-
langtrace_python_sdk/constants/instrumentation/anthropic.py,sha256=
|
128
|
+
langtrace_python_sdk/constants/instrumentation/anthropic.py,sha256=XZjpyILHQsx52Qe926ahisqTCi_iVReCkkj7Pr2gEZ8,241
|
129
129
|
langtrace_python_sdk/constants/instrumentation/aws_bedrock.py,sha256=QwKtO4NBarOZoGkt5cFCcpxAw3zvZxcMMWBbzPPGv-g,422
|
130
130
|
langtrace_python_sdk/constants/instrumentation/chroma.py,sha256=hiPGYdHS0Yj4Kh3eaYBbuCAl_swqIygu80yFqkOgdak,955
|
131
131
|
langtrace_python_sdk/constants/instrumentation/cohere.py,sha256=9yD133VdrYZ5BoJR4nJHlj67gHEImB9-KsD-NkzHW1I,1159
|
@@ -152,8 +152,8 @@ langtrace_python_sdk/instrumentation/agno/__init__.py,sha256=95fn4oA-CHB0mxc6KnV
|
|
152
152
|
langtrace_python_sdk/instrumentation/agno/instrumentation.py,sha256=DWOIEl9Q4IhCFgFQPW3pILdVq_C0RJiaGm_diZ73XJU,3284
|
153
153
|
langtrace_python_sdk/instrumentation/agno/patch.py,sha256=wHMDNiH-XOUTnqC6HKGGbYOp04R8DG2xJqm9Ex_h9AE,22868
|
154
154
|
langtrace_python_sdk/instrumentation/anthropic/__init__.py,sha256=donrurJAGYlxrSRA3BIf76jGeUcAx9Tq8CVpah68S0Y,101
|
155
|
-
langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=
|
156
|
-
langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=
|
155
|
+
langtrace_python_sdk/instrumentation/anthropic/instrumentation.py,sha256=nvRKdf5zj-YbeSpi8moXER5WTi0Oexus6w9E73zsUkc,2033
|
156
|
+
langtrace_python_sdk/instrumentation/anthropic/patch.py,sha256=XEhZd4fL2jt39cs775Xp6DXqFwDml-TWzcsmoZnvtyA,11850
|
157
157
|
langtrace_python_sdk/instrumentation/anthropic/types.py,sha256=WdeXe2tkjAisMLK38STKwVe7MJS5SLoETJ_aKhA_-UU,2463
|
158
158
|
langtrace_python_sdk/instrumentation/autogen/__init__.py,sha256=unDhpqWQIdHFw24lRsRu1Mm1NCZxZgyBrPRZrAJL3Lo,90
|
159
159
|
langtrace_python_sdk/instrumentation/autogen/instrumentation.py,sha256=MVDUCBi6XzLQYmZd6myAounI0HeM8QWX5leuul5Hj0Q,1262
|
@@ -312,8 +312,8 @@ tests/pinecone/cassettes/test_query.yaml,sha256=b5v9G3ssUy00oG63PlFUR3JErF2Js-5A
|
|
312
312
|
tests/pinecone/cassettes/test_upsert.yaml,sha256=neWmQ1v3d03V8WoLl8FoFeeCYImb8pxlJBWnFd_lITU,38607
|
313
313
|
tests/qdrant/conftest.py,sha256=9n0uHxxIjWk9fbYc4bx-uP8lSAgLBVx-cV9UjnsyCHM,381
|
314
314
|
tests/qdrant/test_qdrant.py,sha256=pzjAjVY2kmsmGfrI2Gs2xrolfuaNHz7l1fqGQCjp5_o,3353
|
315
|
-
langtrace_python_sdk-3.8.
|
316
|
-
langtrace_python_sdk-3.8.
|
317
|
-
langtrace_python_sdk-3.8.
|
318
|
-
langtrace_python_sdk-3.8.
|
319
|
-
langtrace_python_sdk-3.8.
|
315
|
+
langtrace_python_sdk-3.8.17.dist-info/METADATA,sha256=feYBeHSHTLTW9hBTvwQxD52bd1Q2eeSpd-8un4fg5Y0,15845
|
316
|
+
langtrace_python_sdk-3.8.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
317
|
+
langtrace_python_sdk-3.8.17.dist-info/entry_points.txt,sha256=1_b9-qvf2fE7uQNZcbUei9vLpFZBbbh9LrtGw95ssAo,70
|
318
|
+
langtrace_python_sdk-3.8.17.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
319
|
+
langtrace_python_sdk-3.8.17.dist-info/RECORD,,
|
File without changes
|
{langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/entry_points.txt
RENAMED
File without changes
|
{langtrace_python_sdk-3.8.15.dist-info → langtrace_python_sdk-3.8.17.dist-info}/licenses/LICENSE
RENAMED
File without changes
|