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.
Files changed (168) hide show
  1. openlit/__helpers.py +235 -86
  2. openlit/__init__.py +16 -13
  3. openlit/_instrumentors.py +2 -1
  4. openlit/evals/all.py +50 -21
  5. openlit/evals/bias_detection.py +47 -20
  6. openlit/evals/hallucination.py +53 -22
  7. openlit/evals/toxicity.py +50 -21
  8. openlit/evals/utils.py +54 -30
  9. openlit/guard/all.py +61 -19
  10. openlit/guard/prompt_injection.py +34 -14
  11. openlit/guard/restrict_topic.py +46 -15
  12. openlit/guard/sensitive_topic.py +34 -14
  13. openlit/guard/utils.py +58 -22
  14. openlit/instrumentation/ag2/__init__.py +24 -8
  15. openlit/instrumentation/ag2/ag2.py +34 -13
  16. openlit/instrumentation/ag2/async_ag2.py +34 -13
  17. openlit/instrumentation/ag2/utils.py +133 -30
  18. openlit/instrumentation/ai21/__init__.py +43 -14
  19. openlit/instrumentation/ai21/ai21.py +47 -21
  20. openlit/instrumentation/ai21/async_ai21.py +47 -21
  21. openlit/instrumentation/ai21/utils.py +299 -78
  22. openlit/instrumentation/anthropic/__init__.py +21 -4
  23. openlit/instrumentation/anthropic/anthropic.py +28 -17
  24. openlit/instrumentation/anthropic/async_anthropic.py +28 -17
  25. openlit/instrumentation/anthropic/utils.py +145 -35
  26. openlit/instrumentation/assemblyai/__init__.py +11 -2
  27. openlit/instrumentation/assemblyai/assemblyai.py +15 -4
  28. openlit/instrumentation/assemblyai/utils.py +120 -25
  29. openlit/instrumentation/astra/__init__.py +43 -10
  30. openlit/instrumentation/astra/astra.py +28 -5
  31. openlit/instrumentation/astra/async_astra.py +28 -5
  32. openlit/instrumentation/astra/utils.py +151 -55
  33. openlit/instrumentation/azure_ai_inference/__init__.py +43 -10
  34. openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +53 -21
  35. openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +53 -21
  36. openlit/instrumentation/azure_ai_inference/utils.py +307 -83
  37. openlit/instrumentation/bedrock/__init__.py +21 -4
  38. openlit/instrumentation/bedrock/bedrock.py +63 -25
  39. openlit/instrumentation/bedrock/utils.py +139 -30
  40. openlit/instrumentation/chroma/__init__.py +89 -16
  41. openlit/instrumentation/chroma/chroma.py +28 -6
  42. openlit/instrumentation/chroma/utils.py +167 -51
  43. openlit/instrumentation/cohere/__init__.py +63 -18
  44. openlit/instrumentation/cohere/async_cohere.py +63 -24
  45. openlit/instrumentation/cohere/cohere.py +63 -24
  46. openlit/instrumentation/cohere/utils.py +286 -73
  47. openlit/instrumentation/controlflow/__init__.py +35 -9
  48. openlit/instrumentation/controlflow/controlflow.py +66 -33
  49. openlit/instrumentation/crawl4ai/__init__.py +25 -10
  50. openlit/instrumentation/crawl4ai/async_crawl4ai.py +78 -31
  51. openlit/instrumentation/crawl4ai/crawl4ai.py +78 -31
  52. openlit/instrumentation/crewai/__init__.py +40 -15
  53. openlit/instrumentation/crewai/async_crewai.py +32 -7
  54. openlit/instrumentation/crewai/crewai.py +32 -7
  55. openlit/instrumentation/crewai/utils.py +159 -56
  56. openlit/instrumentation/dynamiq/__init__.py +46 -12
  57. openlit/instrumentation/dynamiq/dynamiq.py +74 -33
  58. openlit/instrumentation/elevenlabs/__init__.py +23 -4
  59. openlit/instrumentation/elevenlabs/async_elevenlabs.py +16 -4
  60. openlit/instrumentation/elevenlabs/elevenlabs.py +16 -4
  61. openlit/instrumentation/elevenlabs/utils.py +128 -25
  62. openlit/instrumentation/embedchain/__init__.py +11 -2
  63. openlit/instrumentation/embedchain/embedchain.py +68 -35
  64. openlit/instrumentation/firecrawl/__init__.py +24 -7
  65. openlit/instrumentation/firecrawl/firecrawl.py +46 -20
  66. openlit/instrumentation/google_ai_studio/__init__.py +45 -10
  67. openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +67 -44
  68. openlit/instrumentation/google_ai_studio/google_ai_studio.py +67 -44
  69. openlit/instrumentation/google_ai_studio/utils.py +180 -67
  70. openlit/instrumentation/gpt4all/__init__.py +22 -7
  71. openlit/instrumentation/gpt4all/gpt4all.py +67 -29
  72. openlit/instrumentation/gpt4all/utils.py +285 -61
  73. openlit/instrumentation/gpu/__init__.py +128 -47
  74. openlit/instrumentation/groq/__init__.py +21 -4
  75. openlit/instrumentation/groq/async_groq.py +33 -21
  76. openlit/instrumentation/groq/groq.py +33 -21
  77. openlit/instrumentation/groq/utils.py +192 -55
  78. openlit/instrumentation/haystack/__init__.py +70 -24
  79. openlit/instrumentation/haystack/async_haystack.py +28 -6
  80. openlit/instrumentation/haystack/haystack.py +28 -6
  81. openlit/instrumentation/haystack/utils.py +196 -74
  82. openlit/instrumentation/julep/__init__.py +69 -19
  83. openlit/instrumentation/julep/async_julep.py +53 -27
  84. openlit/instrumentation/julep/julep.py +53 -28
  85. openlit/instrumentation/langchain/__init__.py +74 -63
  86. openlit/instrumentation/langchain/callback_handler.py +1100 -0
  87. openlit/instrumentation/langchain_community/__init__.py +13 -2
  88. openlit/instrumentation/langchain_community/async_langchain_community.py +23 -5
  89. openlit/instrumentation/langchain_community/langchain_community.py +23 -5
  90. openlit/instrumentation/langchain_community/utils.py +35 -9
  91. openlit/instrumentation/letta/__init__.py +68 -15
  92. openlit/instrumentation/letta/letta.py +99 -54
  93. openlit/instrumentation/litellm/__init__.py +43 -14
  94. openlit/instrumentation/litellm/async_litellm.py +51 -26
  95. openlit/instrumentation/litellm/litellm.py +51 -26
  96. openlit/instrumentation/litellm/utils.py +304 -102
  97. openlit/instrumentation/llamaindex/__init__.py +267 -90
  98. openlit/instrumentation/llamaindex/async_llamaindex.py +28 -6
  99. openlit/instrumentation/llamaindex/llamaindex.py +28 -6
  100. openlit/instrumentation/llamaindex/utils.py +204 -91
  101. openlit/instrumentation/mem0/__init__.py +11 -2
  102. openlit/instrumentation/mem0/mem0.py +50 -29
  103. openlit/instrumentation/milvus/__init__.py +10 -2
  104. openlit/instrumentation/milvus/milvus.py +31 -6
  105. openlit/instrumentation/milvus/utils.py +166 -67
  106. openlit/instrumentation/mistral/__init__.py +63 -18
  107. openlit/instrumentation/mistral/async_mistral.py +63 -24
  108. openlit/instrumentation/mistral/mistral.py +63 -24
  109. openlit/instrumentation/mistral/utils.py +277 -69
  110. openlit/instrumentation/multion/__init__.py +69 -19
  111. openlit/instrumentation/multion/async_multion.py +57 -26
  112. openlit/instrumentation/multion/multion.py +57 -26
  113. openlit/instrumentation/ollama/__init__.py +39 -18
  114. openlit/instrumentation/ollama/async_ollama.py +57 -26
  115. openlit/instrumentation/ollama/ollama.py +57 -26
  116. openlit/instrumentation/ollama/utils.py +226 -50
  117. openlit/instrumentation/openai/__init__.py +156 -32
  118. openlit/instrumentation/openai/async_openai.py +147 -67
  119. openlit/instrumentation/openai/openai.py +150 -67
  120. openlit/instrumentation/openai/utils.py +657 -185
  121. openlit/instrumentation/openai_agents/__init__.py +5 -1
  122. openlit/instrumentation/openai_agents/processor.py +110 -90
  123. openlit/instrumentation/phidata/__init__.py +13 -5
  124. openlit/instrumentation/phidata/phidata.py +67 -32
  125. openlit/instrumentation/pinecone/__init__.py +48 -9
  126. openlit/instrumentation/pinecone/async_pinecone.py +27 -5
  127. openlit/instrumentation/pinecone/pinecone.py +27 -5
  128. openlit/instrumentation/pinecone/utils.py +153 -47
  129. openlit/instrumentation/premai/__init__.py +22 -7
  130. openlit/instrumentation/premai/premai.py +51 -26
  131. openlit/instrumentation/premai/utils.py +246 -59
  132. openlit/instrumentation/pydantic_ai/__init__.py +49 -22
  133. openlit/instrumentation/pydantic_ai/pydantic_ai.py +69 -16
  134. openlit/instrumentation/pydantic_ai/utils.py +89 -24
  135. openlit/instrumentation/qdrant/__init__.py +19 -4
  136. openlit/instrumentation/qdrant/async_qdrant.py +33 -7
  137. openlit/instrumentation/qdrant/qdrant.py +33 -7
  138. openlit/instrumentation/qdrant/utils.py +228 -93
  139. openlit/instrumentation/reka/__init__.py +23 -10
  140. openlit/instrumentation/reka/async_reka.py +17 -11
  141. openlit/instrumentation/reka/reka.py +17 -11
  142. openlit/instrumentation/reka/utils.py +138 -36
  143. openlit/instrumentation/together/__init__.py +44 -12
  144. openlit/instrumentation/together/async_together.py +50 -27
  145. openlit/instrumentation/together/together.py +50 -27
  146. openlit/instrumentation/together/utils.py +301 -71
  147. openlit/instrumentation/transformers/__init__.py +2 -1
  148. openlit/instrumentation/transformers/transformers.py +13 -3
  149. openlit/instrumentation/transformers/utils.py +139 -36
  150. openlit/instrumentation/vertexai/__init__.py +81 -16
  151. openlit/instrumentation/vertexai/async_vertexai.py +33 -15
  152. openlit/instrumentation/vertexai/utils.py +123 -27
  153. openlit/instrumentation/vertexai/vertexai.py +33 -15
  154. openlit/instrumentation/vllm/__init__.py +12 -5
  155. openlit/instrumentation/vllm/utils.py +121 -31
  156. openlit/instrumentation/vllm/vllm.py +16 -10
  157. openlit/otel/events.py +35 -10
  158. openlit/otel/metrics.py +32 -24
  159. openlit/otel/tracing.py +24 -9
  160. openlit/semcov/__init__.py +72 -6
  161. {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/METADATA +2 -1
  162. openlit-1.34.31.dist-info/RECORD +166 -0
  163. openlit/instrumentation/langchain/async_langchain.py +0 -102
  164. openlit/instrumentation/langchain/langchain.py +0 -102
  165. openlit/instrumentation/langchain/utils.py +0 -252
  166. openlit-1.34.30.dist-info/RECORD +0 -168
  167. {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/LICENSE +0 -0
  168. {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/WHEEL +0 -0
@@ -1,9 +1,14 @@
1
1
  """
2
2
  Together AI OpenTelemetry instrumentation utility functions
3
3
  """
4
+
4
5
  import time
5
6
 
6
- from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
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 (
@@ -16,6 +21,7 @@ from openlit.__helpers import (
16
21
  )
17
22
  from openlit.semcov import SemanticConvention
18
23
 
24
+
19
25
  def format_content(messages):
20
26
  """
21
27
  Process a list of messages to extract content.
@@ -28,8 +34,9 @@ def format_content(messages):
28
34
 
29
35
  if isinstance(content, list):
30
36
  content_str = ", ".join(
31
- f'{item["type"]}: {item["text"] if "text" in item else item["image_url"]}'
32
- if "type" in item else f'text: {item["text"]}'
37
+ f"{item['type']}: {item['text'] if 'text' in item else item['image_url']}"
38
+ if "type" in item
39
+ else f"text: {item['text']}"
33
40
  for item in content
34
41
  )
35
42
  formatted_messages.append(f"{role}: {content_str}")
@@ -38,6 +45,7 @@ def format_content(messages):
38
45
 
39
46
  return "\n".join(formatted_messages)
40
47
 
48
+
41
49
  def process_chunk(scope, chunk):
42
50
  """
43
51
  Process a chunk of response data and update state.
@@ -53,9 +61,10 @@ def process_chunk(scope, chunk):
53
61
 
54
62
  chunked = response_as_dict(chunk)
55
63
  # Collect message IDs and aggregated response from events
56
- if (len(chunked.get("choices")) > 0 and ("delta" in chunked.get("choices")[0] and
57
- "content" in chunked.get("choices")[0].get("delta"))):
58
-
64
+ if len(chunked.get("choices")) > 0 and (
65
+ "delta" in chunked.get("choices")[0]
66
+ and "content" in chunked.get("choices")[0].get("delta")
67
+ ):
59
68
  content = chunked.get("choices")[0].get("delta").get("content")
60
69
  if content:
61
70
  scope._llmresponse += content
@@ -68,8 +77,22 @@ def process_chunk(scope, chunk):
68
77
  scope._finish_reason = str(chunked.get("finish_reason"))
69
78
  scope._end_time = time.time()
70
79
 
71
- def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_address, server_port,
72
- request_model, response_model, environment, application_name, is_stream, tbt, ttft, version):
80
+
81
+ def common_span_attributes(
82
+ scope,
83
+ gen_ai_operation,
84
+ gen_ai_system,
85
+ server_address,
86
+ server_port,
87
+ request_model,
88
+ response_model,
89
+ environment,
90
+ application_name,
91
+ is_stream,
92
+ tbt,
93
+ ttft,
94
+ version,
95
+ ):
73
96
  """
74
97
  Set common span attributes for both chat and RAG operations.
75
98
  """
@@ -88,9 +111,25 @@ def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_addres
88
111
  scope._span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT, ttft)
89
112
  scope._span.set_attribute(SemanticConvention.GEN_AI_SDK_VERSION, version)
90
113
 
91
- def record_common_metrics(metrics, gen_ai_operation, gen_ai_system, server_address, server_port,
92
- request_model, response_model, environment, application_name, start_time, end_time,
93
- input_tokens, output_tokens, cost, tbt=None, ttft=None):
114
+
115
+ def record_common_metrics(
116
+ metrics,
117
+ gen_ai_operation,
118
+ gen_ai_system,
119
+ server_address,
120
+ server_port,
121
+ request_model,
122
+ response_model,
123
+ environment,
124
+ application_name,
125
+ start_time,
126
+ end_time,
127
+ input_tokens,
128
+ output_tokens,
129
+ cost,
130
+ tbt=None,
131
+ ttft=None,
132
+ ):
94
133
  """
95
134
  Record common metrics for the operation.
96
135
  """
@@ -109,15 +148,27 @@ def record_common_metrics(metrics, gen_ai_operation, gen_ai_system, server_addre
109
148
  metrics["genai_requests"].add(1, attributes)
110
149
  metrics["genai_prompt_tokens"].add(input_tokens, attributes)
111
150
  metrics["genai_completion_tokens"].add(output_tokens, attributes)
112
- metrics["genai_client_usage_tokens"].record(input_tokens + output_tokens, attributes)
151
+ metrics["genai_client_usage_tokens"].record(
152
+ input_tokens + output_tokens, attributes
153
+ )
113
154
  metrics["genai_cost"].record(cost, attributes)
114
155
  if tbt is not None:
115
156
  metrics["genai_server_tbt"].record(tbt, attributes)
116
157
  if ttft is not None:
117
158
  metrics["genai_server_ttft"].record(ttft, attributes)
118
159
 
119
- def common_chat_logic(scope, pricing_info, environment, application_name, metrics,
120
- capture_message_content, disable_metrics, version, is_stream):
160
+
161
+ def common_chat_logic(
162
+ scope,
163
+ pricing_info,
164
+ environment,
165
+ application_name,
166
+ metrics,
167
+ capture_message_content,
168
+ disable_metrics,
169
+ version,
170
+ is_stream,
171
+ ):
121
172
  """
122
173
  Process chat request and generate Telemetry
123
174
  """
@@ -128,42 +179,94 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
128
179
  prompt = format_content(scope._kwargs.get("messages", ""))
129
180
  request_model = scope._kwargs.get("model", "jamba-1.5-mini")
130
181
 
131
- cost = get_chat_model_cost(request_model, pricing_info, scope._input_tokens, scope._output_tokens)
182
+ cost = get_chat_model_cost(
183
+ request_model, pricing_info, scope._input_tokens, scope._output_tokens
184
+ )
132
185
 
133
186
  # Common Span Attributes
134
- common_span_attributes(scope,
135
- SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
136
- scope._server_address, scope._server_port, request_model, scope._response_model,
137
- environment, application_name, is_stream, scope._tbt, scope._ttft, version)
187
+ common_span_attributes(
188
+ scope,
189
+ SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
190
+ SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
191
+ scope._server_address,
192
+ scope._server_port,
193
+ request_model,
194
+ scope._response_model,
195
+ environment,
196
+ application_name,
197
+ is_stream,
198
+ scope._tbt,
199
+ scope._ttft,
200
+ version,
201
+ )
138
202
 
139
203
  # Span Attributes for Response parameters
140
- scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason])
141
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SEED, scope._kwargs.get("seed", ""))
142
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY, scope._kwargs.get("frequency_penalty", 0.0))
143
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS, scope._kwargs.get("max_tokens", -1))
144
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY, scope._kwargs.get("presence_penalty", 0.0))
145
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, scope._kwargs.get("stop", []))
146
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, scope._kwargs.get("temperature", 1.0))
147
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0))
204
+ scope._span.set_attribute(
205
+ SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason]
206
+ )
207
+ scope._span.set_attribute(
208
+ SemanticConvention.GEN_AI_REQUEST_SEED, scope._kwargs.get("seed", "")
209
+ )
210
+ scope._span.set_attribute(
211
+ SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY,
212
+ scope._kwargs.get("frequency_penalty", 0.0),
213
+ )
214
+ scope._span.set_attribute(
215
+ SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS,
216
+ scope._kwargs.get("max_tokens", -1),
217
+ )
218
+ scope._span.set_attribute(
219
+ SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY,
220
+ scope._kwargs.get("presence_penalty", 0.0),
221
+ )
222
+ scope._span.set_attribute(
223
+ SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, scope._kwargs.get("stop", [])
224
+ )
225
+ scope._span.set_attribute(
226
+ SemanticConvention.GEN_AI_REQUEST_TEMPERATURE,
227
+ scope._kwargs.get("temperature", 1.0),
228
+ )
229
+ scope._span.set_attribute(
230
+ SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0)
231
+ )
148
232
  scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
149
- scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, "text" if isinstance(scope._llmresponse, str) else "json")
233
+ scope._span.set_attribute(
234
+ SemanticConvention.GEN_AI_OUTPUT_TYPE,
235
+ "text" if isinstance(scope._llmresponse, str) else "json",
236
+ )
150
237
 
151
238
  # Span Attributes for Cost and Tokens
152
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens)
153
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, scope._output_tokens)
154
- scope._span.set_attribute(SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, scope._input_tokens + scope._output_tokens)
239
+ scope._span.set_attribute(
240
+ SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens
241
+ )
242
+ scope._span.set_attribute(
243
+ SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, scope._output_tokens
244
+ )
245
+ scope._span.set_attribute(
246
+ SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE,
247
+ scope._input_tokens + scope._output_tokens,
248
+ )
155
249
  scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
156
250
 
157
251
  # Span Attributes for Tools
158
252
  if scope._tools:
159
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_NAME, scope._tools.get("function","")).get("name","")
160
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_CALL_ID, str(scope._tools.get("id","")))
161
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_ARGS, str(scope._tools.get("function","").get("arguments","")))
253
+ scope._span.set_attribute(
254
+ SemanticConvention.GEN_AI_TOOL_NAME, scope._tools.get("function", "")
255
+ ).get("name", "")
256
+ scope._span.set_attribute(
257
+ SemanticConvention.GEN_AI_TOOL_CALL_ID, str(scope._tools.get("id", ""))
258
+ )
259
+ scope._span.set_attribute(
260
+ SemanticConvention.GEN_AI_TOOL_ARGS,
261
+ str(scope._tools.get("function", "").get("arguments", "")),
262
+ )
162
263
 
163
264
  # Span Attributes for Content
164
265
  if capture_message_content:
165
266
  scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_PROMPT, prompt)
166
- scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse)
267
+ scope._span.set_attribute(
268
+ SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse
269
+ )
167
270
 
168
271
  # To be removed one the change to span_attributes (from span events) is complete
169
272
  scope._span.add_event(
@@ -183,22 +286,68 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
183
286
 
184
287
  # Metrics
185
288
  if not disable_metrics:
186
- record_common_metrics(metrics, SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT, SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
187
- scope._server_address, scope._server_port, request_model, scope._response_model, environment,
188
- application_name, scope._start_time, scope._end_time, scope._input_tokens, scope._output_tokens,
189
- cost, scope._tbt, scope._ttft)
289
+ record_common_metrics(
290
+ metrics,
291
+ SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
292
+ SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
293
+ scope._server_address,
294
+ scope._server_port,
295
+ request_model,
296
+ scope._response_model,
297
+ environment,
298
+ application_name,
299
+ scope._start_time,
300
+ scope._end_time,
301
+ scope._input_tokens,
302
+ scope._output_tokens,
303
+ cost,
304
+ scope._tbt,
305
+ scope._ttft,
306
+ )
190
307
 
191
- def process_streaming_chat_response(scope, pricing_info, environment, application_name, metrics,
192
- capture_message_content=False, disable_metrics=False, version=""):
308
+
309
+ def process_streaming_chat_response(
310
+ scope,
311
+ pricing_info,
312
+ environment,
313
+ application_name,
314
+ metrics,
315
+ capture_message_content=False,
316
+ disable_metrics=False,
317
+ version="",
318
+ ):
193
319
  """
194
320
  Process chat request and generate Telemetry
195
321
  """
196
- common_chat_logic(scope, pricing_info, environment, application_name, metrics,
197
- capture_message_content, disable_metrics, version, is_stream=True)
322
+ common_chat_logic(
323
+ scope,
324
+ pricing_info,
325
+ environment,
326
+ application_name,
327
+ metrics,
328
+ capture_message_content,
329
+ disable_metrics,
330
+ version,
331
+ is_stream=True,
332
+ )
198
333
 
199
- def process_chat_response(response, request_model, pricing_info, server_port, server_address,
200
- environment, application_name, metrics, start_time, span, capture_message_content=False,
201
- disable_metrics=False, version="1.0.0", **kwargs):
334
+
335
+ def process_chat_response(
336
+ response,
337
+ request_model,
338
+ pricing_info,
339
+ server_port,
340
+ server_address,
341
+ environment,
342
+ application_name,
343
+ metrics,
344
+ start_time,
345
+ span,
346
+ capture_message_content=False,
347
+ disable_metrics=False,
348
+ version="1.0.0",
349
+ **kwargs,
350
+ ):
202
351
  """
203
352
  Process chat request and generate Telemetry
204
353
  """
@@ -228,57 +377,105 @@ def process_chat_response(response, request_model, pricing_info, server_port, se
228
377
  else:
229
378
  scope._tools = None
230
379
 
231
- common_chat_logic(scope, pricing_info, environment, application_name, metrics,
232
- capture_message_content, disable_metrics, version, is_stream=False)
380
+ common_chat_logic(
381
+ scope,
382
+ pricing_info,
383
+ environment,
384
+ application_name,
385
+ metrics,
386
+ capture_message_content,
387
+ disable_metrics,
388
+ version,
389
+ is_stream=False,
390
+ )
233
391
 
234
392
  return response
235
393
 
236
- def common_image_logic(scope, pricing_info, environment, application_name, metrics,
237
- capture_message_content, disable_metrics, version):
394
+
395
+ def common_image_logic(
396
+ scope,
397
+ pricing_info,
398
+ environment,
399
+ application_name,
400
+ metrics,
401
+ capture_message_content,
402
+ disable_metrics,
403
+ version,
404
+ ):
238
405
  """
239
406
  Process image generation request and generate Telemetry
240
407
  """
241
408
 
242
409
  # Find Image format
243
- if "response_format" in scope._kwargs and scope._kwargs["response_format"] == "b64_json":
410
+ if (
411
+ "response_format" in scope._kwargs
412
+ and scope._kwargs["response_format"] == "b64_json"
413
+ ):
244
414
  image_format = "b64_json"
245
415
  else:
246
416
  image_format = "url"
247
417
 
248
- image_size = str(scope._kwargs.get("width", "1024")) + "x" + str(scope._kwargs.get("height", "1024"))
418
+ image_size = (
419
+ str(scope._kwargs.get("width", "1024"))
420
+ + "x"
421
+ + str(scope._kwargs.get("height", "1024"))
422
+ )
249
423
  request_model = scope._kwargs.get("model", "dall-e-2")
250
424
 
251
425
  # Calculate cost of the operation
252
- cost = get_image_model_cost(request_model, pricing_info, image_size,
253
- scope._kwargs.get("quality", "standard"))
426
+ cost = get_image_model_cost(
427
+ request_model,
428
+ pricing_info,
429
+ image_size,
430
+ scope._kwargs.get("quality", "standard"),
431
+ )
254
432
 
255
433
  # Common Span Attributes
256
- common_span_attributes(scope,
257
- SemanticConvention.GEN_AI_OPERATION_TYPE_IMAGE, SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
258
- scope._server_address, scope._server_port, request_model, scope._response_model,
259
- environment, application_name, False, scope._tbt, scope._ttft, version)
434
+ common_span_attributes(
435
+ scope,
436
+ SemanticConvention.GEN_AI_OPERATION_TYPE_IMAGE,
437
+ SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
438
+ scope._server_address,
439
+ scope._server_port,
440
+ request_model,
441
+ scope._response_model,
442
+ environment,
443
+ application_name,
444
+ False,
445
+ scope._tbt,
446
+ scope._ttft,
447
+ version,
448
+ )
260
449
 
261
450
  # Image-specific span attributes
262
451
  scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
263
452
  scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, "image")
264
453
  scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IMAGE_SIZE, image_size)
265
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, len(scope._response_data) * cost)
454
+ scope._span.set_attribute(
455
+ SemanticConvention.GEN_AI_USAGE_COST, len(scope._response_data) * cost
456
+ )
266
457
 
267
458
  # Content attributes
268
459
  if capture_message_content:
269
460
  scope._span.add_event(
270
461
  name=SemanticConvention.GEN_AI_CONTENT_PROMPT_EVENT,
271
462
  attributes={
272
- SemanticConvention.GEN_AI_CONTENT_PROMPT: scope._kwargs.get("prompt", ""),
463
+ SemanticConvention.GEN_AI_CONTENT_PROMPT: scope._kwargs.get(
464
+ "prompt", ""
465
+ ),
273
466
  },
274
467
  )
275
468
 
276
469
  for images_count, item in enumerate(scope._response_data):
277
- attribute_name = f"{SemanticConvention.GEN_AI_RESPONSE_IMAGE}.{images_count}"
470
+ attribute_name = (
471
+ f"{SemanticConvention.GEN_AI_RESPONSE_IMAGE}.{images_count}"
472
+ )
278
473
  scope._span.add_event(
279
474
  name=attribute_name,
280
475
  attributes={
281
- SemanticConvention.GEN_AI_CONTENT_COMPLETION: getattr(item, image_format),
476
+ SemanticConvention.GEN_AI_CONTENT_COMPLETION: getattr(
477
+ item, image_format
478
+ ),
282
479
  },
283
480
  )
284
481
 
@@ -287,15 +484,40 @@ def common_image_logic(scope, pricing_info, environment, application_name, metri
287
484
  # Metrics
288
485
  if not disable_metrics:
289
486
  record_common_metrics(
290
- metrics, SemanticConvention.GEN_AI_OPERATION_TYPE_IMAGE,
291
- SemanticConvention.GEN_AI_SYSTEM_TOGETHER, scope._server_address, scope._server_port,
292
- request_model, scope._response_model, environment, application_name,
293
- scope._start_time, scope._end_time, 0, 0, len(scope._response_data) * cost
487
+ metrics,
488
+ SemanticConvention.GEN_AI_OPERATION_TYPE_IMAGE,
489
+ SemanticConvention.GEN_AI_SYSTEM_TOGETHER,
490
+ scope._server_address,
491
+ scope._server_port,
492
+ request_model,
493
+ scope._response_model,
494
+ environment,
495
+ application_name,
496
+ scope._start_time,
497
+ scope._end_time,
498
+ 0,
499
+ 0,
500
+ len(scope._response_data) * cost,
294
501
  )
295
502
 
296
- def process_image_response(response, request_model, pricing_info, server_address, server_port,
297
- environment, application_name, metrics, start_time, end_time, span, capture_message_content,
298
- disable_metrics, version, **kwargs):
503
+
504
+ def process_image_response(
505
+ response,
506
+ request_model,
507
+ pricing_info,
508
+ server_address,
509
+ server_port,
510
+ environment,
511
+ application_name,
512
+ metrics,
513
+ start_time,
514
+ end_time,
515
+ span,
516
+ capture_message_content,
517
+ disable_metrics,
518
+ version,
519
+ **kwargs,
520
+ ):
299
521
  """
300
522
  Process image generation request and generate Telemetry
301
523
  """
@@ -314,7 +536,15 @@ def process_image_response(response, request_model, pricing_info, server_address
314
536
  scope._tbt = 0
315
537
  scope._ttft = end_time - start_time
316
538
 
317
- common_image_logic(scope, pricing_info, environment, application_name, metrics,
318
- capture_message_content, disable_metrics, version)
539
+ common_image_logic(
540
+ scope,
541
+ pricing_info,
542
+ environment,
543
+ application_name,
544
+ metrics,
545
+ capture_message_content,
546
+ disable_metrics,
547
+ version,
548
+ )
319
549
 
320
550
  return response
@@ -11,6 +11,7 @@ from openlit.instrumentation.transformers.transformers import pipeline_wrapper
11
11
 
12
12
  _instruments = ("transformers >= 4.48.0",)
13
13
 
14
+
14
15
  class TransformersInstrumentor(BaseInstrumentor):
15
16
  """
16
17
  An instrumentor for HuggingFace Transformer library.
@@ -40,7 +41,7 @@ class TransformersInstrumentor(BaseInstrumentor):
40
41
  pricing_info,
41
42
  capture_message_content,
42
43
  metrics,
43
- disable_metrics
44
+ disable_metrics,
44
45
  ),
45
46
  )
46
47
 
@@ -9,8 +9,16 @@ from openlit.instrumentation.transformers.utils import process_chat_response
9
9
  from openlit.semcov import SemanticConvention
10
10
 
11
11
 
12
- def pipeline_wrapper(version, environment, application_name, tracer, pricing_info,
13
- capture_message_content, metrics, disable_metrics):
12
+ def pipeline_wrapper(
13
+ version,
14
+ environment,
15
+ application_name,
16
+ tracer,
17
+ pricing_info,
18
+ capture_message_content,
19
+ metrics,
20
+ disable_metrics,
21
+ ):
14
22
  """
15
23
  Generates a telemetry wrapper for GenAI function call
16
24
  """
@@ -20,7 +28,9 @@ def pipeline_wrapper(version, environment, application_name, tracer, pricing_inf
20
28
  Wraps the GenAI function call.
21
29
  """
22
30
 
23
- server_address, server_port = set_server_address_and_port(instance, "127.0.0.1", 80)
31
+ server_address, server_port = set_server_address_and_port(
32
+ instance, "127.0.0.1", 80
33
+ )
24
34
  request_model = instance.model.config.name_or_path
25
35
 
26
36
  span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"