langtrace-python-sdk 2.1.29__py3-none-any.whl → 2.2.1__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.
- examples/cohere_example/chat.py +1 -0
- examples/cohere_example/chat_stream.py +3 -0
- examples/gemini_example/__init__.py +6 -0
- examples/gemini_example/function_tools.py +62 -0
- examples/gemini_example/main.py +91 -0
- examples/langchain_example/__init__.py +8 -0
- examples/langchain_example/groq_example.py +28 -15
- examples/ollama_example/basic.py +1 -0
- examples/openai_example/__init__.py +1 -0
- examples/openai_example/async_tool_calling_nonstreaming.py +1 -1
- examples/openai_example/chat_completion.py +1 -1
- examples/openai_example/embeddings_create.py +1 -0
- examples/openai_example/images_edit.py +2 -2
- examples/vertexai_example/__init__.py +6 -0
- examples/vertexai_example/main.py +214 -0
- langtrace_python_sdk/constants/instrumentation/common.py +2 -0
- langtrace_python_sdk/constants/instrumentation/gemini.py +12 -0
- langtrace_python_sdk/constants/instrumentation/vertexai.py +42 -0
- langtrace_python_sdk/instrumentation/__init__.py +4 -0
- langtrace_python_sdk/instrumentation/anthropic/patch.py +68 -96
- langtrace_python_sdk/instrumentation/chroma/patch.py +29 -29
- langtrace_python_sdk/instrumentation/cohere/patch.py +143 -242
- langtrace_python_sdk/instrumentation/gemini/__init__.py +3 -0
- langtrace_python_sdk/instrumentation/gemini/instrumentation.py +36 -0
- langtrace_python_sdk/instrumentation/gemini/patch.py +186 -0
- langtrace_python_sdk/instrumentation/groq/patch.py +82 -125
- langtrace_python_sdk/instrumentation/ollama/patch.py +62 -65
- langtrace_python_sdk/instrumentation/openai/patch.py +190 -494
- langtrace_python_sdk/instrumentation/qdrant/patch.py +6 -6
- langtrace_python_sdk/instrumentation/vertexai/__init__.py +3 -0
- langtrace_python_sdk/instrumentation/vertexai/instrumentation.py +33 -0
- langtrace_python_sdk/instrumentation/vertexai/patch.py +131 -0
- langtrace_python_sdk/langtrace.py +5 -0
- langtrace_python_sdk/utils/__init__.py +14 -3
- langtrace_python_sdk/utils/llm.py +311 -6
- langtrace_python_sdk/version.py +1 -1
- {langtrace_python_sdk-2.1.29.dist-info → langtrace_python_sdk-2.2.1.dist-info}/METADATA +26 -19
- {langtrace_python_sdk-2.1.29.dist-info → langtrace_python_sdk-2.2.1.dist-info}/RECORD +55 -36
- tests/anthropic/test_anthropic.py +28 -27
- tests/cohere/test_cohere_chat.py +36 -36
- tests/cohere/test_cohere_embed.py +12 -9
- tests/cohere/test_cohere_rerank.py +18 -11
- tests/groq/cassettes/test_async_chat_completion.yaml +113 -0
- tests/groq/cassettes/test_async_chat_completion_streaming.yaml +2232 -0
- tests/groq/cassettes/test_chat_completion.yaml +114 -0
- tests/groq/cassettes/test_chat_completion_streaming.yaml +2512 -0
- tests/groq/conftest.py +33 -0
- tests/groq/test_groq.py +142 -0
- tests/openai/cassettes/test_async_chat_completion_streaming.yaml +28 -28
- tests/openai/test_chat_completion.py +53 -67
- tests/openai/test_image_generation.py +47 -24
- tests/utils.py +40 -5
- {langtrace_python_sdk-2.1.29.dist-info → langtrace_python_sdk-2.2.1.dist-info}/WHEEL +0 -0
- {langtrace_python_sdk-2.1.29.dist-info → langtrace_python_sdk-2.2.1.dist-info}/entry_points.txt +0 -0
- {langtrace_python_sdk-2.1.29.dist-info → langtrace_python_sdk-2.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,41 +1,35 @@
|
|
|
1
1
|
from langtrace_python_sdk.constants.instrumentation.ollama import APIS
|
|
2
|
-
from importlib_metadata import version as v
|
|
3
|
-
from langtrace_python_sdk.constants import LANGTRACE_SDK_NAME
|
|
4
2
|
from langtrace_python_sdk.utils import set_span_attribute
|
|
5
|
-
from langtrace_python_sdk.utils.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
from langtrace_python_sdk.utils.llm import (
|
|
4
|
+
get_extra_attributes,
|
|
5
|
+
get_langtrace_attributes,
|
|
6
|
+
get_llm_request_attributes,
|
|
7
|
+
get_llm_url,
|
|
8
|
+
set_event_completion,
|
|
9
9
|
)
|
|
10
|
-
from
|
|
10
|
+
from langtrace_python_sdk.utils.silently_fail import silently_fail
|
|
11
|
+
from langtrace_python_sdk.constants.instrumentation.common import SERVICE_PROVIDERS
|
|
11
12
|
from langtrace.trace_attributes import LLMSpanAttributes, Event
|
|
12
13
|
from opentelemetry.trace import SpanKind
|
|
13
14
|
import json
|
|
14
15
|
from opentelemetry.trace.status import Status, StatusCode
|
|
16
|
+
from langtrace.trace_attributes import SpanAttributes
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def generic_patch(operation_name, version, tracer):
|
|
18
20
|
def traced_method(wrapped, instance, args, kwargs):
|
|
19
|
-
base_url = (
|
|
20
|
-
str(instance._client._base_url)
|
|
21
|
-
if hasattr(instance, "_client") and hasattr(instance._client, "_base_url")
|
|
22
|
-
else ""
|
|
23
|
-
)
|
|
24
21
|
api = APIS[operation_name]
|
|
25
22
|
service_provider = SERVICE_PROVIDERS["OLLAMA"]
|
|
26
|
-
extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
|
|
27
23
|
span_attributes = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"llm.response_format": kwargs.get("format"),
|
|
38
|
-
**(extra_attributes if extra_attributes is not None else {}),
|
|
24
|
+
**get_langtrace_attributes(version, service_provider),
|
|
25
|
+
**get_llm_request_attributes(
|
|
26
|
+
kwargs,
|
|
27
|
+
prompts=kwargs.get("messages", None),
|
|
28
|
+
),
|
|
29
|
+
**get_llm_url(instance),
|
|
30
|
+
SpanAttributes.LLM_PATH: api["ENDPOINT"],
|
|
31
|
+
SpanAttributes.LLM_RESPONSE_FORMAT: kwargs.get("format"),
|
|
32
|
+
**get_extra_attributes(),
|
|
39
33
|
}
|
|
40
34
|
|
|
41
35
|
attributes = LLMSpanAttributes(**span_attributes)
|
|
@@ -77,24 +71,14 @@ def ageneric_patch(operation_name, version, tracer):
|
|
|
77
71
|
async def traced_method(wrapped, instance, args, kwargs):
|
|
78
72
|
api = APIS[operation_name]
|
|
79
73
|
service_provider = SERVICE_PROVIDERS["OLLAMA"]
|
|
80
|
-
extra_attributes = baggage.get_baggage(LANGTRACE_ADDITIONAL_SPAN_ATTRIBUTES_KEY)
|
|
81
74
|
span_attributes = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"langtrace.version": v(LANGTRACE_SDK_NAME),
|
|
89
|
-
"llm.model": kwargs.get("model"),
|
|
90
|
-
"llm.stream": kwargs.get("stream"),
|
|
91
|
-
"llm.response_format": kwargs.get("format"),
|
|
92
|
-
"http.timeout": (
|
|
93
|
-
kwargs.get("keep_alive") if "keep_alive" in kwargs else None
|
|
94
|
-
),
|
|
95
|
-
**(extra_attributes if extra_attributes is not None else {}),
|
|
75
|
+
**get_langtrace_attributes(version, service_provider),
|
|
76
|
+
**get_llm_request_attributes(kwargs),
|
|
77
|
+
**get_llm_url(instance),
|
|
78
|
+
SpanAttributes.LLM_PATH: api["ENDPOINT"],
|
|
79
|
+
SpanAttributes.LLM_RESPONSE_FORMAT: kwargs.get("format"),
|
|
80
|
+
**get_extra_attributes(),
|
|
96
81
|
}
|
|
97
|
-
|
|
98
82
|
attributes = LLMSpanAttributes(**span_attributes)
|
|
99
83
|
with tracer.start_as_current_span(api["METHOD"], kind=SpanKind.CLIENT) as span:
|
|
100
84
|
_set_input_attributes(span, kwargs, attributes)
|
|
@@ -130,23 +114,25 @@ def _set_response_attributes(span, response):
|
|
|
130
114
|
input_tokens = response.get("prompt_eval_count") or 0
|
|
131
115
|
output_tokens = response.get("eval_count") or 0
|
|
132
116
|
total_tokens = input_tokens + output_tokens
|
|
133
|
-
usage_dict = {
|
|
134
|
-
"input_tokens": input_tokens,
|
|
135
|
-
"output_tokens": output_tokens,
|
|
136
|
-
"total_tokens": total_tokens,
|
|
137
|
-
}
|
|
138
117
|
|
|
139
118
|
if total_tokens > 0:
|
|
140
|
-
set_span_attribute(span,
|
|
141
|
-
|
|
119
|
+
set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens)
|
|
120
|
+
set_span_attribute(
|
|
121
|
+
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, output_tokens
|
|
122
|
+
)
|
|
123
|
+
set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens)
|
|
124
|
+
|
|
125
|
+
set_span_attribute(
|
|
126
|
+
span,
|
|
127
|
+
SpanAttributes.LLM_RESPONSE_FINISH_REASON,
|
|
128
|
+
response.get("done_reason"),
|
|
129
|
+
)
|
|
142
130
|
if "message" in response:
|
|
143
|
-
|
|
131
|
+
set_event_completion(span, [response.get("message")])
|
|
144
132
|
|
|
145
133
|
if "response" in response:
|
|
146
|
-
|
|
147
|
-
span,
|
|
148
|
-
"llm.responses",
|
|
149
|
-
json.dumps([{"role": "assistant", "content": response.get("response")}]),
|
|
134
|
+
set_event_completion(
|
|
135
|
+
span, [{"role": "assistant", "content": response.get("response")}]
|
|
150
136
|
)
|
|
151
137
|
|
|
152
138
|
|
|
@@ -156,26 +142,23 @@ def _set_input_attributes(span, kwargs, attributes):
|
|
|
156
142
|
|
|
157
143
|
for field, value in attributes.model_dump(by_alias=True).items():
|
|
158
144
|
set_span_attribute(span, field, value)
|
|
159
|
-
|
|
145
|
+
|
|
146
|
+
if "options" in kwargs:
|
|
160
147
|
set_span_attribute(
|
|
161
148
|
span,
|
|
162
|
-
|
|
163
|
-
|
|
149
|
+
SpanAttributes.LLM_REQUEST_TEMPERATURE,
|
|
150
|
+
options.get("temperature"),
|
|
164
151
|
)
|
|
165
|
-
|
|
152
|
+
set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, options.get("top_p"))
|
|
166
153
|
set_span_attribute(
|
|
167
154
|
span,
|
|
168
|
-
|
|
169
|
-
|
|
155
|
+
SpanAttributes.LLM_FREQUENCY_PENALTY,
|
|
156
|
+
options.get("frequency_penalty"),
|
|
170
157
|
)
|
|
171
|
-
if "options" in kwargs:
|
|
172
|
-
set_span_attribute(span, "llm.temperature", options.get("temperature"))
|
|
173
|
-
set_span_attribute(span, "llm.top_p", options.get("top_p"))
|
|
174
158
|
set_span_attribute(
|
|
175
|
-
span,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
span, "llm.presence_penalty", options.get("presence_penalty")
|
|
159
|
+
span,
|
|
160
|
+
SpanAttributes.LLM_PRESENCE_PENALTY,
|
|
161
|
+
options.get("presence_penalty"),
|
|
179
162
|
)
|
|
180
163
|
|
|
181
164
|
|
|
@@ -194,6 +177,14 @@ def _handle_streaming_response(span, response, api):
|
|
|
194
177
|
if api == "generate":
|
|
195
178
|
accumulated_tokens["response"] += chunk["response"]
|
|
196
179
|
|
|
180
|
+
span.add_event(
|
|
181
|
+
Event.STREAM_OUTPUT.value,
|
|
182
|
+
{
|
|
183
|
+
SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK: chunk.get("response")
|
|
184
|
+
or chunk.get("message").get("content"),
|
|
185
|
+
},
|
|
186
|
+
)
|
|
187
|
+
|
|
197
188
|
_set_response_attributes(span, chunk | accumulated_tokens)
|
|
198
189
|
finally:
|
|
199
190
|
# Finalize span after processing all chunks
|
|
@@ -220,6 +211,12 @@ async def _ahandle_streaming_response(span, response, api):
|
|
|
220
211
|
if api == "generate":
|
|
221
212
|
accumulated_tokens["response"] += chunk["response"]
|
|
222
213
|
|
|
214
|
+
span.add_event(
|
|
215
|
+
Event.STREAM_OUTPUT.value,
|
|
216
|
+
{
|
|
217
|
+
SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK: json.dumps(chunk),
|
|
218
|
+
},
|
|
219
|
+
)
|
|
223
220
|
_set_response_attributes(span, chunk | accumulated_tokens)
|
|
224
221
|
finally:
|
|
225
222
|
# Finalize span after processing all chunks
|