openlit 1.34.30__py3-none-any.whl → 1.34.31__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.
- openlit/__helpers.py +235 -86
- openlit/__init__.py +16 -13
- openlit/_instrumentors.py +2 -1
- openlit/evals/all.py +50 -21
- openlit/evals/bias_detection.py +47 -20
- openlit/evals/hallucination.py +53 -22
- openlit/evals/toxicity.py +50 -21
- openlit/evals/utils.py +54 -30
- openlit/guard/all.py +61 -19
- openlit/guard/prompt_injection.py +34 -14
- openlit/guard/restrict_topic.py +46 -15
- openlit/guard/sensitive_topic.py +34 -14
- openlit/guard/utils.py +58 -22
- openlit/instrumentation/ag2/__init__.py +24 -8
- openlit/instrumentation/ag2/ag2.py +34 -13
- openlit/instrumentation/ag2/async_ag2.py +34 -13
- openlit/instrumentation/ag2/utils.py +133 -30
- openlit/instrumentation/ai21/__init__.py +43 -14
- openlit/instrumentation/ai21/ai21.py +47 -21
- openlit/instrumentation/ai21/async_ai21.py +47 -21
- openlit/instrumentation/ai21/utils.py +299 -78
- openlit/instrumentation/anthropic/__init__.py +21 -4
- openlit/instrumentation/anthropic/anthropic.py +28 -17
- openlit/instrumentation/anthropic/async_anthropic.py +28 -17
- openlit/instrumentation/anthropic/utils.py +145 -35
- openlit/instrumentation/assemblyai/__init__.py +11 -2
- openlit/instrumentation/assemblyai/assemblyai.py +15 -4
- openlit/instrumentation/assemblyai/utils.py +120 -25
- openlit/instrumentation/astra/__init__.py +43 -10
- openlit/instrumentation/astra/astra.py +28 -5
- openlit/instrumentation/astra/async_astra.py +28 -5
- openlit/instrumentation/astra/utils.py +151 -55
- openlit/instrumentation/azure_ai_inference/__init__.py +43 -10
- openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/utils.py +307 -83
- openlit/instrumentation/bedrock/__init__.py +21 -4
- openlit/instrumentation/bedrock/bedrock.py +63 -25
- openlit/instrumentation/bedrock/utils.py +139 -30
- openlit/instrumentation/chroma/__init__.py +89 -16
- openlit/instrumentation/chroma/chroma.py +28 -6
- openlit/instrumentation/chroma/utils.py +167 -51
- openlit/instrumentation/cohere/__init__.py +63 -18
- openlit/instrumentation/cohere/async_cohere.py +63 -24
- openlit/instrumentation/cohere/cohere.py +63 -24
- openlit/instrumentation/cohere/utils.py +286 -73
- openlit/instrumentation/controlflow/__init__.py +35 -9
- openlit/instrumentation/controlflow/controlflow.py +66 -33
- openlit/instrumentation/crawl4ai/__init__.py +25 -10
- openlit/instrumentation/crawl4ai/async_crawl4ai.py +78 -31
- openlit/instrumentation/crawl4ai/crawl4ai.py +78 -31
- openlit/instrumentation/crewai/__init__.py +40 -15
- openlit/instrumentation/crewai/async_crewai.py +32 -7
- openlit/instrumentation/crewai/crewai.py +32 -7
- openlit/instrumentation/crewai/utils.py +159 -56
- openlit/instrumentation/dynamiq/__init__.py +46 -12
- openlit/instrumentation/dynamiq/dynamiq.py +74 -33
- openlit/instrumentation/elevenlabs/__init__.py +23 -4
- openlit/instrumentation/elevenlabs/async_elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/utils.py +128 -25
- openlit/instrumentation/embedchain/__init__.py +11 -2
- openlit/instrumentation/embedchain/embedchain.py +68 -35
- openlit/instrumentation/firecrawl/__init__.py +24 -7
- openlit/instrumentation/firecrawl/firecrawl.py +46 -20
- openlit/instrumentation/google_ai_studio/__init__.py +45 -10
- openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/utils.py +180 -67
- openlit/instrumentation/gpt4all/__init__.py +22 -7
- openlit/instrumentation/gpt4all/gpt4all.py +67 -29
- openlit/instrumentation/gpt4all/utils.py +285 -61
- openlit/instrumentation/gpu/__init__.py +128 -47
- openlit/instrumentation/groq/__init__.py +21 -4
- openlit/instrumentation/groq/async_groq.py +33 -21
- openlit/instrumentation/groq/groq.py +33 -21
- openlit/instrumentation/groq/utils.py +192 -55
- openlit/instrumentation/haystack/__init__.py +70 -24
- openlit/instrumentation/haystack/async_haystack.py +28 -6
- openlit/instrumentation/haystack/haystack.py +28 -6
- openlit/instrumentation/haystack/utils.py +196 -74
- openlit/instrumentation/julep/__init__.py +69 -19
- openlit/instrumentation/julep/async_julep.py +53 -27
- openlit/instrumentation/julep/julep.py +53 -28
- openlit/instrumentation/langchain/__init__.py +74 -63
- openlit/instrumentation/langchain/callback_handler.py +1100 -0
- openlit/instrumentation/langchain_community/__init__.py +13 -2
- openlit/instrumentation/langchain_community/async_langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/utils.py +35 -9
- openlit/instrumentation/letta/__init__.py +68 -15
- openlit/instrumentation/letta/letta.py +99 -54
- openlit/instrumentation/litellm/__init__.py +43 -14
- openlit/instrumentation/litellm/async_litellm.py +51 -26
- openlit/instrumentation/litellm/litellm.py +51 -26
- openlit/instrumentation/litellm/utils.py +304 -102
- openlit/instrumentation/llamaindex/__init__.py +267 -90
- openlit/instrumentation/llamaindex/async_llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/utils.py +204 -91
- openlit/instrumentation/mem0/__init__.py +11 -2
- openlit/instrumentation/mem0/mem0.py +50 -29
- openlit/instrumentation/milvus/__init__.py +10 -2
- openlit/instrumentation/milvus/milvus.py +31 -6
- openlit/instrumentation/milvus/utils.py +166 -67
- openlit/instrumentation/mistral/__init__.py +63 -18
- openlit/instrumentation/mistral/async_mistral.py +63 -24
- openlit/instrumentation/mistral/mistral.py +63 -24
- openlit/instrumentation/mistral/utils.py +277 -69
- openlit/instrumentation/multion/__init__.py +69 -19
- openlit/instrumentation/multion/async_multion.py +57 -26
- openlit/instrumentation/multion/multion.py +57 -26
- openlit/instrumentation/ollama/__init__.py +39 -18
- openlit/instrumentation/ollama/async_ollama.py +57 -26
- openlit/instrumentation/ollama/ollama.py +57 -26
- openlit/instrumentation/ollama/utils.py +226 -50
- openlit/instrumentation/openai/__init__.py +156 -32
- openlit/instrumentation/openai/async_openai.py +147 -67
- openlit/instrumentation/openai/openai.py +150 -67
- openlit/instrumentation/openai/utils.py +657 -185
- openlit/instrumentation/openai_agents/__init__.py +5 -1
- openlit/instrumentation/openai_agents/processor.py +110 -90
- openlit/instrumentation/phidata/__init__.py +13 -5
- openlit/instrumentation/phidata/phidata.py +67 -32
- openlit/instrumentation/pinecone/__init__.py +48 -9
- openlit/instrumentation/pinecone/async_pinecone.py +27 -5
- openlit/instrumentation/pinecone/pinecone.py +27 -5
- openlit/instrumentation/pinecone/utils.py +153 -47
- openlit/instrumentation/premai/__init__.py +22 -7
- openlit/instrumentation/premai/premai.py +51 -26
- openlit/instrumentation/premai/utils.py +246 -59
- openlit/instrumentation/pydantic_ai/__init__.py +49 -22
- openlit/instrumentation/pydantic_ai/pydantic_ai.py +69 -16
- openlit/instrumentation/pydantic_ai/utils.py +89 -24
- openlit/instrumentation/qdrant/__init__.py +19 -4
- openlit/instrumentation/qdrant/async_qdrant.py +33 -7
- openlit/instrumentation/qdrant/qdrant.py +33 -7
- openlit/instrumentation/qdrant/utils.py +228 -93
- openlit/instrumentation/reka/__init__.py +23 -10
- openlit/instrumentation/reka/async_reka.py +17 -11
- openlit/instrumentation/reka/reka.py +17 -11
- openlit/instrumentation/reka/utils.py +138 -36
- openlit/instrumentation/together/__init__.py +44 -12
- openlit/instrumentation/together/async_together.py +50 -27
- openlit/instrumentation/together/together.py +50 -27
- openlit/instrumentation/together/utils.py +301 -71
- openlit/instrumentation/transformers/__init__.py +2 -1
- openlit/instrumentation/transformers/transformers.py +13 -3
- openlit/instrumentation/transformers/utils.py +139 -36
- openlit/instrumentation/vertexai/__init__.py +81 -16
- openlit/instrumentation/vertexai/async_vertexai.py +33 -15
- openlit/instrumentation/vertexai/utils.py +123 -27
- openlit/instrumentation/vertexai/vertexai.py +33 -15
- openlit/instrumentation/vllm/__init__.py +12 -5
- openlit/instrumentation/vllm/utils.py +121 -31
- openlit/instrumentation/vllm/vllm.py +16 -10
- openlit/otel/events.py +35 -10
- openlit/otel/metrics.py +32 -24
- openlit/otel/tracing.py +24 -9
- openlit/semcov/__init__.py +72 -6
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/METADATA +2 -1
- openlit-1.34.31.dist-info/RECORD +166 -0
- openlit/instrumentation/langchain/async_langchain.py +0 -102
- openlit/instrumentation/langchain/langchain.py +0 -102
- openlit/instrumentation/langchain/utils.py +0 -252
- openlit-1.34.30.dist-info/RECORD +0 -168
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/LICENSE +0 -0
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/WHEEL +0 -0
@@ -4,10 +4,7 @@ Module for monitoring Anthropic API calls.
|
|
4
4
|
|
5
5
|
import time
|
6
6
|
from opentelemetry.trace import SpanKind
|
7
|
-
from openlit.__helpers import
|
8
|
-
handle_exception,
|
9
|
-
set_server_address_and_port
|
10
|
-
)
|
7
|
+
from openlit.__helpers import handle_exception, set_server_address_and_port
|
11
8
|
from openlit.instrumentation.anthropic.utils import (
|
12
9
|
process_chunk,
|
13
10
|
process_chat_response,
|
@@ -15,7 +12,17 @@ from openlit.instrumentation.anthropic.utils import (
|
|
15
12
|
)
|
16
13
|
from openlit.semcov import SemanticConvention
|
17
14
|
|
18
|
-
|
15
|
+
|
16
|
+
def async_messages(
|
17
|
+
version,
|
18
|
+
environment,
|
19
|
+
application_name,
|
20
|
+
tracer,
|
21
|
+
pricing_info,
|
22
|
+
capture_message_content,
|
23
|
+
metrics,
|
24
|
+
disable_metrics,
|
25
|
+
):
|
19
26
|
"""
|
20
27
|
Generates a telemetry wrapper for Anthropic AsyncMessages.create calls.
|
21
28
|
"""
|
@@ -26,14 +33,14 @@ def async_messages(version, environment, application_name, tracer, pricing_info,
|
|
26
33
|
"""
|
27
34
|
|
28
35
|
def __init__(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
self,
|
37
|
+
wrapped,
|
38
|
+
span,
|
39
|
+
span_name,
|
40
|
+
kwargs,
|
41
|
+
server_address,
|
42
|
+
server_port,
|
43
|
+
):
|
37
44
|
self.__wrapped__ = wrapped
|
38
45
|
self._span = span
|
39
46
|
self._span_name = span_name
|
@@ -87,7 +94,7 @@ def async_messages(version, environment, application_name, tracer, pricing_info,
|
|
87
94
|
metrics=metrics,
|
88
95
|
capture_message_content=capture_message_content,
|
89
96
|
disable_metrics=disable_metrics,
|
90
|
-
version=version
|
97
|
+
version=version,
|
91
98
|
)
|
92
99
|
except Exception as e:
|
93
100
|
handle_exception(self._span, e)
|
@@ -99,7 +106,9 @@ def async_messages(version, environment, application_name, tracer, pricing_info,
|
|
99
106
|
"""
|
100
107
|
|
101
108
|
streaming = kwargs.get("stream", False)
|
102
|
-
server_address, server_port = set_server_address_and_port(
|
109
|
+
server_address, server_port = set_server_address_and_port(
|
110
|
+
instance, "api.anthropic.com", 443
|
111
|
+
)
|
103
112
|
request_model = kwargs.get("model", "claude-3-5-sonnet-latest")
|
104
113
|
|
105
114
|
span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
|
@@ -109,7 +118,9 @@ def async_messages(version, environment, application_name, tracer, pricing_info,
|
|
109
118
|
awaited_wrapped = await wrapped(*args, **kwargs)
|
110
119
|
span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
|
111
120
|
|
112
|
-
return TracedAsyncStream(
|
121
|
+
return TracedAsyncStream(
|
122
|
+
awaited_wrapped, span, span_name, kwargs, server_address, server_port
|
123
|
+
)
|
113
124
|
|
114
125
|
else:
|
115
126
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
@@ -131,7 +142,7 @@ def async_messages(version, environment, application_name, tracer, pricing_info,
|
|
131
142
|
capture_message_content=capture_message_content,
|
132
143
|
disable_metrics=disable_metrics,
|
133
144
|
version=version,
|
134
|
-
**kwargs
|
145
|
+
**kwargs,
|
135
146
|
)
|
136
147
|
|
137
148
|
except Exception as e:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
Anthropic OpenTelemetry instrumentation utility functions
|
3
3
|
"""
|
4
|
+
|
4
5
|
import time
|
5
6
|
|
6
7
|
from opentelemetry.trace import Status, StatusCode
|
@@ -15,6 +16,7 @@ from openlit.__helpers import (
|
|
15
16
|
)
|
16
17
|
from openlit.semcov import SemanticConvention
|
17
18
|
|
19
|
+
|
18
20
|
def format_content(messages):
|
19
21
|
"""
|
20
22
|
Format the messages into a string for span events.
|
@@ -47,6 +49,7 @@ def format_content(messages):
|
|
47
49
|
|
48
50
|
return "\n".join(formatted_messages)
|
49
51
|
|
52
|
+
|
50
53
|
def process_chunk(scope, chunk):
|
51
54
|
"""
|
52
55
|
Process a chunk of response data and update state.
|
@@ -87,8 +90,18 @@ def process_chunk(scope, chunk):
|
|
87
90
|
scope._output_tokens = chunked.get("usage").get("output_tokens")
|
88
91
|
scope._finish_reason = chunked.get("delta").get("stop_reason")
|
89
92
|
|
90
|
-
|
91
|
-
|
93
|
+
|
94
|
+
def common_chat_logic(
|
95
|
+
scope,
|
96
|
+
pricing_info,
|
97
|
+
environment,
|
98
|
+
application_name,
|
99
|
+
metrics,
|
100
|
+
capture_message_content,
|
101
|
+
disable_metrics,
|
102
|
+
version,
|
103
|
+
is_stream,
|
104
|
+
):
|
92
105
|
"""
|
93
106
|
Process chat request and generate Telemetry
|
94
107
|
"""
|
@@ -100,30 +113,68 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
100
113
|
formatted_messages = format_content(scope._kwargs.get("messages", []))
|
101
114
|
request_model = scope._kwargs.get("model", "claude-3-5-sonnet-latest")
|
102
115
|
|
103
|
-
cost = get_chat_model_cost(
|
116
|
+
cost = get_chat_model_cost(
|
117
|
+
request_model, pricing_info, scope._input_tokens, scope._output_tokens
|
118
|
+
)
|
104
119
|
|
105
120
|
# Common Span Attributes
|
106
|
-
common_span_attributes(
|
107
|
-
|
108
|
-
|
109
|
-
|
121
|
+
common_span_attributes(
|
122
|
+
scope,
|
123
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
124
|
+
SemanticConvention.GEN_AI_SYSTEM_ANTHROPIC,
|
125
|
+
scope._server_address,
|
126
|
+
scope._server_port,
|
127
|
+
request_model,
|
128
|
+
scope._response_model,
|
129
|
+
environment,
|
130
|
+
application_name,
|
131
|
+
is_stream,
|
132
|
+
scope._tbt,
|
133
|
+
scope._ttft,
|
134
|
+
version,
|
135
|
+
)
|
110
136
|
|
111
137
|
# Span Attributes for Request parameters
|
112
|
-
scope._span.set_attribute(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
scope._span.set_attribute(
|
138
|
+
scope._span.set_attribute(
|
139
|
+
SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS,
|
140
|
+
scope._kwargs.get("max_tokens", -1),
|
141
|
+
)
|
142
|
+
scope._span.set_attribute(
|
143
|
+
SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES,
|
144
|
+
scope._kwargs.get("stop_sequences", []),
|
145
|
+
)
|
146
|
+
scope._span.set_attribute(
|
147
|
+
SemanticConvention.GEN_AI_REQUEST_TEMPERATURE,
|
148
|
+
scope._kwargs.get("temperature", 1.0),
|
149
|
+
)
|
150
|
+
scope._span.set_attribute(
|
151
|
+
SemanticConvention.GEN_AI_REQUEST_TOP_K, scope._kwargs.get("top_k", 1.0)
|
152
|
+
)
|
153
|
+
scope._span.set_attribute(
|
154
|
+
SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0)
|
155
|
+
)
|
117
156
|
|
118
157
|
# Span Attributes for Response parameters
|
119
158
|
scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
|
120
|
-
scope._span.set_attribute(
|
121
|
-
|
159
|
+
scope._span.set_attribute(
|
160
|
+
SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason]
|
161
|
+
)
|
162
|
+
scope._span.set_attribute(
|
163
|
+
SemanticConvention.GEN_AI_OUTPUT_TYPE,
|
164
|
+
"text" if isinstance(scope._llmresponse, str) else "json",
|
165
|
+
)
|
122
166
|
|
123
167
|
# Span Attributes for Cost and Tokens
|
124
|
-
scope._span.set_attribute(
|
125
|
-
|
126
|
-
|
168
|
+
scope._span.set_attribute(
|
169
|
+
SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens
|
170
|
+
)
|
171
|
+
scope._span.set_attribute(
|
172
|
+
SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, scope._output_tokens
|
173
|
+
)
|
174
|
+
scope._span.set_attribute(
|
175
|
+
SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE,
|
176
|
+
scope._input_tokens + scope._output_tokens,
|
177
|
+
)
|
127
178
|
scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
|
128
179
|
|
129
180
|
# Handle tool calls if present
|
@@ -139,8 +190,12 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
139
190
|
|
140
191
|
# Span Attributes for Content
|
141
192
|
if capture_message_content:
|
142
|
-
scope._span.set_attribute(
|
143
|
-
|
193
|
+
scope._span.set_attribute(
|
194
|
+
SemanticConvention.GEN_AI_CONTENT_PROMPT, formatted_messages
|
195
|
+
)
|
196
|
+
scope._span.set_attribute(
|
197
|
+
SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse
|
198
|
+
)
|
144
199
|
|
145
200
|
# To be removed once the change to span_attributes (from span events) is complete
|
146
201
|
scope._span.add_event(
|
@@ -160,13 +215,36 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
|
|
160
215
|
|
161
216
|
# Record metrics
|
162
217
|
if not disable_metrics:
|
163
|
-
record_completion_metrics(
|
164
|
-
|
165
|
-
|
166
|
-
|
218
|
+
record_completion_metrics(
|
219
|
+
metrics,
|
220
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
221
|
+
SemanticConvention.GEN_AI_SYSTEM_ANTHROPIC,
|
222
|
+
scope._server_address,
|
223
|
+
scope._server_port,
|
224
|
+
request_model,
|
225
|
+
scope._response_model,
|
226
|
+
environment,
|
227
|
+
application_name,
|
228
|
+
scope._start_time,
|
229
|
+
scope._end_time,
|
230
|
+
scope._input_tokens,
|
231
|
+
scope._output_tokens,
|
232
|
+
cost,
|
233
|
+
scope._tbt,
|
234
|
+
scope._ttft,
|
235
|
+
)
|
167
236
|
|
168
|
-
|
169
|
-
|
237
|
+
|
238
|
+
def process_streaming_chat_response(
|
239
|
+
scope,
|
240
|
+
pricing_info,
|
241
|
+
environment,
|
242
|
+
application_name,
|
243
|
+
metrics,
|
244
|
+
capture_message_content=False,
|
245
|
+
disable_metrics=False,
|
246
|
+
version="",
|
247
|
+
):
|
170
248
|
"""
|
171
249
|
Process streaming chat response and generate telemetry.
|
172
250
|
"""
|
@@ -175,15 +253,38 @@ def process_streaming_chat_response(scope, pricing_info, environment, applicatio
|
|
175
253
|
scope._tool_calls = {
|
176
254
|
"id": scope._tool_id,
|
177
255
|
"name": scope._tool_name,
|
178
|
-
"input": scope._tool_arguments
|
256
|
+
"input": scope._tool_arguments,
|
179
257
|
}
|
180
258
|
|
181
|
-
common_chat_logic(
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
259
|
+
common_chat_logic(
|
260
|
+
scope,
|
261
|
+
pricing_info,
|
262
|
+
environment,
|
263
|
+
application_name,
|
264
|
+
metrics,
|
265
|
+
capture_message_content,
|
266
|
+
disable_metrics,
|
267
|
+
version,
|
268
|
+
is_stream=True,
|
269
|
+
)
|
270
|
+
|
271
|
+
|
272
|
+
def process_chat_response(
|
273
|
+
response,
|
274
|
+
request_model,
|
275
|
+
pricing_info,
|
276
|
+
server_port,
|
277
|
+
server_address,
|
278
|
+
environment,
|
279
|
+
application_name,
|
280
|
+
metrics,
|
281
|
+
start_time,
|
282
|
+
span,
|
283
|
+
capture_message_content=False,
|
284
|
+
disable_metrics=False,
|
285
|
+
version="1.0.0",
|
286
|
+
**kwargs,
|
287
|
+
):
|
187
288
|
"""
|
188
289
|
Process non-streaming chat response and generate telemetry.
|
189
290
|
"""
|
@@ -215,11 +316,20 @@ def process_chat_response(response, request_model, pricing_info, server_port, se
|
|
215
316
|
scope._tool_calls = {
|
216
317
|
"id": block.get("id", ""),
|
217
318
|
"name": block.get("name", ""),
|
218
|
-
"input": block.get("input", "")
|
319
|
+
"input": block.get("input", ""),
|
219
320
|
}
|
220
321
|
break
|
221
322
|
|
222
|
-
common_chat_logic(
|
223
|
-
|
323
|
+
common_chat_logic(
|
324
|
+
scope,
|
325
|
+
pricing_info,
|
326
|
+
environment,
|
327
|
+
application_name,
|
328
|
+
metrics,
|
329
|
+
capture_message_content,
|
330
|
+
disable_metrics,
|
331
|
+
version,
|
332
|
+
is_stream=False,
|
333
|
+
)
|
224
334
|
|
225
335
|
return response
|
@@ -9,6 +9,7 @@ from openlit.instrumentation.assemblyai.assemblyai import transcribe
|
|
9
9
|
|
10
10
|
_instruments = ("assemblyai >= 0.35.1",)
|
11
11
|
|
12
|
+
|
12
13
|
class AssemblyAIInstrumentor(BaseInstrumentor):
|
13
14
|
"""
|
14
15
|
An instrumentor for AssemblyAI client library.
|
@@ -31,8 +32,16 @@ class AssemblyAIInstrumentor(BaseInstrumentor):
|
|
31
32
|
wrap_function_wrapper(
|
32
33
|
"assemblyai.transcriber",
|
33
34
|
"Transcriber.transcribe",
|
34
|
-
transcribe(
|
35
|
-
|
35
|
+
transcribe(
|
36
|
+
version,
|
37
|
+
environment,
|
38
|
+
application_name,
|
39
|
+
tracer,
|
40
|
+
pricing_info,
|
41
|
+
capture_message_content,
|
42
|
+
metrics,
|
43
|
+
disable_metrics,
|
44
|
+
),
|
36
45
|
)
|
37
46
|
|
38
47
|
def _uninstrument(self, **kwargs):
|
@@ -12,8 +12,17 @@ from openlit.semcov import SemanticConvention
|
|
12
12
|
# Initialize logger for logging potential issues and operations
|
13
13
|
logger = logging.getLogger(__name__)
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
def transcribe(
|
17
|
+
version,
|
18
|
+
environment,
|
19
|
+
application_name,
|
20
|
+
tracer,
|
21
|
+
pricing_info,
|
22
|
+
capture_message_content,
|
23
|
+
metrics,
|
24
|
+
disable_metrics,
|
25
|
+
):
|
17
26
|
"""
|
18
27
|
Generates a telemetry wrapper for AssemblyAI transcribe function call
|
19
28
|
"""
|
@@ -23,7 +32,9 @@ def transcribe(version, environment, application_name,
|
|
23
32
|
Wraps the AssemblyAI transcribe function call.
|
24
33
|
"""
|
25
34
|
|
26
|
-
server_address, server_port = set_server_address_and_port(
|
35
|
+
server_address, server_port = set_server_address_and_port(
|
36
|
+
instance, "api.assemblyai.com", 443
|
37
|
+
)
|
27
38
|
request_model = kwargs.get("speech_model", "best")
|
28
39
|
|
29
40
|
span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO} {request_model}"
|
@@ -48,7 +59,7 @@ def transcribe(version, environment, application_name,
|
|
48
59
|
capture_message_content=capture_message_content,
|
49
60
|
disable_metrics=disable_metrics,
|
50
61
|
version=version,
|
51
|
-
**kwargs
|
62
|
+
**kwargs,
|
52
63
|
)
|
53
64
|
|
54
65
|
except Exception as e:
|
@@ -1,9 +1,14 @@
|
|
1
1
|
"""
|
2
2
|
AssemblyAI OpenTelemetry instrumentation utility functions
|
3
3
|
"""
|
4
|
+
|
4
5
|
import time
|
5
6
|
|
6
|
-
from opentelemetry.sdk.resources import
|
7
|
+
from opentelemetry.sdk.resources import (
|
8
|
+
SERVICE_NAME,
|
9
|
+
TELEMETRY_SDK_NAME,
|
10
|
+
DEPLOYMENT_ENVIRONMENT,
|
11
|
+
)
|
7
12
|
from opentelemetry.trace import Status, StatusCode
|
8
13
|
|
9
14
|
from openlit.__helpers import (
|
@@ -12,14 +17,29 @@ from openlit.__helpers import (
|
|
12
17
|
)
|
13
18
|
from openlit.semcov import SemanticConvention
|
14
19
|
|
20
|
+
|
15
21
|
def format_audio_url(audio_url):
|
16
22
|
"""
|
17
23
|
Process audio URL input to extract content.
|
18
24
|
"""
|
19
25
|
return str(audio_url) if audio_url else ""
|
20
26
|
|
21
|
-
|
22
|
-
|
27
|
+
|
28
|
+
def common_span_attributes(
|
29
|
+
scope,
|
30
|
+
gen_ai_operation,
|
31
|
+
gen_ai_system,
|
32
|
+
server_address,
|
33
|
+
server_port,
|
34
|
+
request_model,
|
35
|
+
response_model,
|
36
|
+
environment,
|
37
|
+
application_name,
|
38
|
+
is_stream,
|
39
|
+
tbt,
|
40
|
+
ttft,
|
41
|
+
version,
|
42
|
+
):
|
23
43
|
"""
|
24
44
|
Set common span attributes for both chat and RAG operations.
|
25
45
|
"""
|
@@ -30,7 +50,9 @@ def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_addres
|
|
30
50
|
scope._span.set_attribute(SemanticConvention.SERVER_ADDRESS, server_address)
|
31
51
|
scope._span.set_attribute(SemanticConvention.SERVER_PORT, server_port)
|
32
52
|
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL, request_model)
|
33
|
-
scope._span.set_attribute(
|
53
|
+
scope._span.set_attribute(
|
54
|
+
SemanticConvention.GEN_AI_RESPONSE_MODEL, scope._response_model
|
55
|
+
)
|
34
56
|
scope._span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
|
35
57
|
scope._span.set_attribute(SERVICE_NAME, application_name)
|
36
58
|
scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IS_STREAM, is_stream)
|
@@ -38,8 +60,21 @@ def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_addres
|
|
38
60
|
scope._span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT, scope._ttft)
|
39
61
|
scope._span.set_attribute(SemanticConvention.GEN_AI_SDK_VERSION, version)
|
40
62
|
|
41
|
-
|
42
|
-
|
63
|
+
|
64
|
+
def record_audio_metrics(
|
65
|
+
metrics,
|
66
|
+
gen_ai_operation,
|
67
|
+
gen_ai_system,
|
68
|
+
server_address,
|
69
|
+
server_port,
|
70
|
+
request_model,
|
71
|
+
response_model,
|
72
|
+
environment,
|
73
|
+
application_name,
|
74
|
+
start_time,
|
75
|
+
end_time,
|
76
|
+
cost,
|
77
|
+
):
|
43
78
|
"""
|
44
79
|
Record audio metrics for the operation.
|
45
80
|
"""
|
@@ -58,8 +93,18 @@ def record_audio_metrics(metrics, gen_ai_operation, gen_ai_system, server_addres
|
|
58
93
|
metrics["genai_requests"].add(1, attributes)
|
59
94
|
metrics["genai_cost"].record(cost, attributes)
|
60
95
|
|
61
|
-
|
62
|
-
|
96
|
+
|
97
|
+
def common_audio_logic(
|
98
|
+
scope,
|
99
|
+
gen_ai_endpoint,
|
100
|
+
pricing_info,
|
101
|
+
environment,
|
102
|
+
application_name,
|
103
|
+
metrics,
|
104
|
+
capture_message_content,
|
105
|
+
disable_metrics,
|
106
|
+
version,
|
107
|
+
):
|
63
108
|
"""
|
64
109
|
Process audio transcription request and generate Telemetry
|
65
110
|
"""
|
@@ -69,13 +114,26 @@ def common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, applic
|
|
69
114
|
is_stream = False
|
70
115
|
|
71
116
|
# Calculate cost based on audio duration
|
72
|
-
cost = get_audio_model_cost(
|
117
|
+
cost = get_audio_model_cost(
|
118
|
+
request_model, pricing_info, prompt, scope._response.audio_duration
|
119
|
+
)
|
73
120
|
|
74
121
|
# Common Span Attributes
|
75
|
-
common_span_attributes(
|
76
|
-
|
77
|
-
|
78
|
-
|
122
|
+
common_span_attributes(
|
123
|
+
scope,
|
124
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO,
|
125
|
+
SemanticConvention.GEN_AI_SYSTEM_ASSEMBLYAI,
|
126
|
+
scope._server_address,
|
127
|
+
scope._server_port,
|
128
|
+
request_model,
|
129
|
+
request_model,
|
130
|
+
environment,
|
131
|
+
application_name,
|
132
|
+
is_stream,
|
133
|
+
scope._tbt,
|
134
|
+
scope._ttft,
|
135
|
+
version,
|
136
|
+
)
|
79
137
|
|
80
138
|
# Span Attributes for Response parameters
|
81
139
|
scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, "text")
|
@@ -85,12 +143,16 @@ def common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, applic
|
|
85
143
|
scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
|
86
144
|
|
87
145
|
# Audio-specific span attributes
|
88
|
-
scope._span.set_attribute(
|
146
|
+
scope._span.set_attribute(
|
147
|
+
SemanticConvention.GEN_AI_REQUEST_AUDIO_DURATION, scope._response.audio_duration
|
148
|
+
)
|
89
149
|
|
90
150
|
# Span Attributes for Content
|
91
151
|
if capture_message_content:
|
92
152
|
scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_PROMPT, prompt)
|
93
|
-
scope._span.set_attribute(
|
153
|
+
scope._span.set_attribute(
|
154
|
+
SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._response.text
|
155
|
+
)
|
94
156
|
|
95
157
|
# To be removed once the change to span_attributes (from span events) is complete
|
96
158
|
scope._span.add_event(
|
@@ -110,14 +172,38 @@ def common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, applic
|
|
110
172
|
|
111
173
|
# Metrics
|
112
174
|
if not disable_metrics:
|
113
|
-
record_audio_metrics(
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
175
|
+
record_audio_metrics(
|
176
|
+
metrics,
|
177
|
+
SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO,
|
178
|
+
SemanticConvention.GEN_AI_SYSTEM_ASSEMBLYAI,
|
179
|
+
scope._server_address,
|
180
|
+
scope._server_port,
|
181
|
+
request_model,
|
182
|
+
request_model,
|
183
|
+
environment,
|
184
|
+
application_name,
|
185
|
+
scope._start_time,
|
186
|
+
scope._end_time,
|
187
|
+
cost,
|
188
|
+
)
|
189
|
+
|
190
|
+
|
191
|
+
def process_audio_response(
|
192
|
+
response,
|
193
|
+
gen_ai_endpoint,
|
194
|
+
pricing_info,
|
195
|
+
server_port,
|
196
|
+
server_address,
|
197
|
+
environment,
|
198
|
+
application_name,
|
199
|
+
metrics,
|
200
|
+
start_time,
|
201
|
+
span,
|
202
|
+
capture_message_content=False,
|
203
|
+
disable_metrics=False,
|
204
|
+
version="1.0.0",
|
205
|
+
**kwargs,
|
206
|
+
):
|
121
207
|
"""
|
122
208
|
Process audio transcription request and generate Telemetry
|
123
209
|
"""
|
@@ -136,7 +222,16 @@ def process_audio_response(response, gen_ai_endpoint, pricing_info, server_port,
|
|
136
222
|
scope._tbt = 0.0
|
137
223
|
scope._ttft = scope._end_time - scope._start_time
|
138
224
|
|
139
|
-
common_audio_logic(
|
140
|
-
|
225
|
+
common_audio_logic(
|
226
|
+
scope,
|
227
|
+
gen_ai_endpoint,
|
228
|
+
pricing_info,
|
229
|
+
environment,
|
230
|
+
application_name,
|
231
|
+
metrics,
|
232
|
+
capture_message_content,
|
233
|
+
disable_metrics,
|
234
|
+
version,
|
235
|
+
)
|
141
236
|
|
142
237
|
return response
|