openlit 1.34.29__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 +111 -24
  53. openlit/instrumentation/crewai/async_crewai.py +114 -0
  54. openlit/instrumentation/crewai/crewai.py +104 -131
  55. openlit/instrumentation/crewai/utils.py +615 -0
  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 +312 -101
  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 +660 -186
  121. openlit/instrumentation/openai_agents/__init__.py +6 -2
  122. openlit/instrumentation/openai_agents/processor.py +409 -537
  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 +101 -7
  161. {openlit-1.34.29.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.29.dist-info/RECORD +0 -166
  167. {openlit-1.34.29.dist-info → openlit-1.34.31.dist-info}/LICENSE +0 -0
  168. {openlit-1.34.29.dist-info → openlit-1.34.31.dist-info}/WHEEL +0 -0
@@ -5,12 +5,11 @@ import importlib.metadata
5
5
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
6
6
  from wrapt import wrap_function_wrapper
7
7
 
8
- from openlit.instrumentation.premai.premai import (
9
- chat, embedding
10
- )
8
+ from openlit.instrumentation.premai.premai import chat, embedding
11
9
 
12
10
  _instruments = ("premai >= 0.3.79",)
13
11
 
12
+
14
13
  class PremAIInstrumentor(BaseInstrumentor):
15
14
  """
16
15
  An instrumentor for Prem AI's client library.
@@ -33,16 +32,32 @@ class PremAIInstrumentor(BaseInstrumentor):
33
32
  wrap_function_wrapper(
34
33
  "premai.api",
35
34
  "ChatCompletionsModule.create",
36
- chat(version, environment, application_name,
37
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
35
+ chat(
36
+ version,
37
+ environment,
38
+ application_name,
39
+ tracer,
40
+ pricing_info,
41
+ capture_message_content,
42
+ metrics,
43
+ disable_metrics,
44
+ ),
38
45
  )
39
46
 
40
47
  # sync embedding
41
48
  wrap_function_wrapper(
42
49
  "premai.api",
43
50
  "EmbeddingsModule.create",
44
- embedding(version, environment, application_name,
45
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
51
+ embedding(
52
+ version,
53
+ environment,
54
+ application_name,
55
+ tracer,
56
+ pricing_info,
57
+ capture_message_content,
58
+ metrics,
59
+ disable_metrics,
60
+ ),
46
61
  )
47
62
 
48
63
  def _uninstrument(self, **kwargs):
@@ -4,20 +4,26 @@ Module for monitoring PremAI 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.premai.utils import (
12
9
  process_chat_response,
13
10
  process_chunk,
14
11
  process_streaming_chat_response,
15
- process_embedding_response
12
+ process_embedding_response,
16
13
  )
17
14
  from openlit.semcov import SemanticConvention
18
15
 
19
- def chat(version, environment, application_name,
20
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
16
+
17
+ def chat(
18
+ version,
19
+ environment,
20
+ application_name,
21
+ tracer,
22
+ pricing_info,
23
+ capture_message_content,
24
+ metrics,
25
+ disable_metrics,
26
+ ):
21
27
  """
22
28
  Generates a telemetry wrapper for GenAI function call
23
29
  """
@@ -28,15 +34,15 @@ def chat(version, environment, application_name,
28
34
  """
29
35
 
30
36
  def __init__(
31
- self,
32
- wrapped,
33
- span,
34
- span_name,
35
- kwargs,
36
- server_address,
37
- server_port,
38
- **args,
39
- ):
37
+ self,
38
+ wrapped,
39
+ span,
40
+ span_name,
41
+ kwargs,
42
+ server_address,
43
+ server_port,
44
+ **args,
45
+ ):
40
46
  self.__wrapped__ = wrapped
41
47
  self._span = span
42
48
  self._span_name = span_name
@@ -75,7 +81,9 @@ def chat(version, environment, application_name,
75
81
 
76
82
  finally:
77
83
  try:
78
- with tracer.start_as_current_span(self._span_name, kind=SpanKind.CLIENT) as self._span:
84
+ with tracer.start_as_current_span(
85
+ self._span_name, kind=SpanKind.CLIENT
86
+ ) as self._span:
79
87
  process_streaming_chat_response(
80
88
  self,
81
89
  pricing_info=pricing_info,
@@ -84,7 +92,7 @@ def chat(version, environment, application_name,
84
92
  metrics=metrics,
85
93
  capture_message_content=capture_message_content,
86
94
  disable_metrics=disable_metrics,
87
- version=version
95
+ version=version,
88
96
  )
89
97
 
90
98
  except Exception as e:
@@ -98,7 +106,9 @@ def chat(version, environment, application_name,
98
106
  # Check if streaming is enabled for the API call
99
107
  streaming = kwargs.get("stream", False)
100
108
 
101
- server_address, server_port = set_server_address_and_port(instance, "app.premai.io", 443)
109
+ server_address, server_port = set_server_address_and_port(
110
+ instance, "app.premai.io", 443
111
+ )
102
112
  request_model = kwargs.get("model", "gpt-4o-mini")
103
113
 
104
114
  span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
@@ -107,7 +117,9 @@ def chat(version, environment, application_name,
107
117
  # Special handling for streaming response to accommodate the nature of data flow
108
118
  awaited_wrapped = wrapped(*args, **kwargs)
109
119
  span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
110
- return TracedSyncStream(awaited_wrapped, span, span_name, kwargs, server_address, server_port)
120
+ return TracedSyncStream(
121
+ awaited_wrapped, span, span_name, kwargs, server_address, server_port
122
+ )
111
123
 
112
124
  # Handling for non-streaming responses
113
125
  else:
@@ -130,7 +142,7 @@ def chat(version, environment, application_name,
130
142
  capture_message_content=capture_message_content,
131
143
  disable_metrics=disable_metrics,
132
144
  version=version,
133
- **kwargs
145
+ **kwargs,
134
146
  )
135
147
 
136
148
  except Exception as e:
@@ -140,8 +152,17 @@ def chat(version, environment, application_name,
140
152
 
141
153
  return wrapper
142
154
 
143
- def embedding(version, environment, application_name,
144
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
155
+
156
+ def embedding(
157
+ version,
158
+ environment,
159
+ application_name,
160
+ tracer,
161
+ pricing_info,
162
+ capture_message_content,
163
+ metrics,
164
+ disable_metrics,
165
+ ):
145
166
  """
146
167
  Generates a telemetry wrapper for GenAI function call
147
168
  """
@@ -151,10 +172,14 @@ def embedding(version, environment, application_name,
151
172
  Wraps the GenAI function call.
152
173
  """
153
174
 
154
- server_address, server_port = set_server_address_and_port(instance, "app.premai.io", 443)
175
+ server_address, server_port = set_server_address_and_port(
176
+ instance, "app.premai.io", 443
177
+ )
155
178
  request_model = kwargs.get("model", "text-embedding-ada-002")
156
179
 
157
- span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
180
+ span_name = (
181
+ f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
182
+ )
158
183
 
159
184
  with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
160
185
  start_time = time.time()
@@ -175,7 +200,7 @@ def embedding(version, environment, application_name,
175
200
  capture_message_content=capture_message_content,
176
201
  disable_metrics=disable_metrics,
177
202
  version=version,
178
- **kwargs
203
+ **kwargs,
179
204
  )
180
205
 
181
206
  except Exception as e:
@@ -1,6 +1,7 @@
1
1
  """
2
2
  PremAI OpenTelemetry instrumentation utility functions
3
3
  """
4
+
4
5
  import time
5
6
 
6
7
  from opentelemetry.trace import Status, StatusCode
@@ -18,6 +19,7 @@ from openlit.__helpers import (
18
19
  )
19
20
  from openlit.semcov import SemanticConvention
20
21
 
22
+
21
23
  def format_content(messages):
22
24
  """
23
25
  Process a list of messages to extract content.
@@ -30,8 +32,9 @@ def format_content(messages):
30
32
 
31
33
  if isinstance(content, list):
32
34
  content_str = ", ".join(
33
- f'{item["type"]}: {item["text"] if "text" in item else item["image_url"]}'
34
- if "type" in item else f'text: {item["text"]}'
35
+ f"{item['type']}: {item['text'] if 'text' in item else item['image_url']}"
36
+ if "type" in item
37
+ else f"text: {item['text']}"
35
38
  for item in content
36
39
  )
37
40
  formatted_messages.append(f"{role}: {content_str}")
@@ -40,6 +43,7 @@ def format_content(messages):
40
43
 
41
44
  return "\n".join(formatted_messages)
42
45
 
46
+
43
47
  def process_chunk(scope, chunk):
44
48
  """
45
49
  Process a chunk of response data and update state.
@@ -67,8 +71,18 @@ def process_chunk(scope, chunk):
67
71
  scope._response_model = chunked.get("model")
68
72
  scope._end_time = time.time()
69
73
 
70
- def common_chat_logic(scope, pricing_info, environment, application_name, metrics,
71
- capture_message_content, disable_metrics, version, is_stream):
74
+
75
+ def common_chat_logic(
76
+ scope,
77
+ pricing_info,
78
+ environment,
79
+ application_name,
80
+ metrics,
81
+ capture_message_content,
82
+ disable_metrics,
83
+ version,
84
+ is_stream,
85
+ ):
72
86
  """
73
87
  Process chat request and generate Telemetry
74
88
  """
@@ -90,40 +104,91 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
90
104
  cost = get_chat_model_cost(request_model, pricing_info, input_tokens, output_tokens)
91
105
 
92
106
  # Common Span Attributes
93
- common_span_attributes(scope,
94
- SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,SemanticConvention.GEN_AI_SYSTEM_PREMAI,
95
- scope._server_address, scope._server_port, request_model, scope._response_model,
96
- environment, application_name, is_stream, scope._tbt, scope._ttft, version)
107
+ common_span_attributes(
108
+ scope,
109
+ SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
110
+ SemanticConvention.GEN_AI_SYSTEM_PREMAI,
111
+ scope._server_address,
112
+ scope._server_port,
113
+ request_model,
114
+ scope._response_model,
115
+ environment,
116
+ application_name,
117
+ is_stream,
118
+ scope._tbt,
119
+ scope._ttft,
120
+ version,
121
+ )
97
122
 
98
123
  # Span Attributes for Response parameters
99
- scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason])
100
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SEED, scope._kwargs.get("seed", ""))
101
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY, scope._kwargs.get("frequency_penalty", 0.0))
102
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS, scope._kwargs.get("max_tokens", -1))
103
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY, scope._kwargs.get("presence_penalty", 0.0))
104
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, scope._kwargs.get("stop", []))
105
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, scope._kwargs.get("temperature", 1.0))
106
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0))
107
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_USER, scope._kwargs.get("user", ""))
124
+ scope._span.set_attribute(
125
+ SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [scope._finish_reason]
126
+ )
127
+ scope._span.set_attribute(
128
+ SemanticConvention.GEN_AI_REQUEST_SEED, scope._kwargs.get("seed", "")
129
+ )
130
+ scope._span.set_attribute(
131
+ SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY,
132
+ scope._kwargs.get("frequency_penalty", 0.0),
133
+ )
134
+ scope._span.set_attribute(
135
+ SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS,
136
+ scope._kwargs.get("max_tokens", -1),
137
+ )
138
+ scope._span.set_attribute(
139
+ SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY,
140
+ scope._kwargs.get("presence_penalty", 0.0),
141
+ )
142
+ scope._span.set_attribute(
143
+ SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, scope._kwargs.get("stop", [])
144
+ )
145
+ scope._span.set_attribute(
146
+ SemanticConvention.GEN_AI_REQUEST_TEMPERATURE,
147
+ scope._kwargs.get("temperature", 1.0),
148
+ )
149
+ scope._span.set_attribute(
150
+ SemanticConvention.GEN_AI_REQUEST_TOP_P, scope._kwargs.get("top_p", 1.0)
151
+ )
152
+ scope._span.set_attribute(
153
+ SemanticConvention.GEN_AI_REQUEST_USER, scope._kwargs.get("user", "")
154
+ )
108
155
  scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, scope._response_id)
109
- scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, "text" if isinstance(scope._llmresponse, str) else "json")
156
+ scope._span.set_attribute(
157
+ SemanticConvention.GEN_AI_OUTPUT_TYPE,
158
+ "text" if isinstance(scope._llmresponse, str) else "json",
159
+ )
110
160
 
111
161
  # Span Attributes for Cost and Tokens
112
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
113
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
114
- scope._span.set_attribute(SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, input_tokens + output_tokens)
162
+ scope._span.set_attribute(
163
+ SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, input_tokens
164
+ )
165
+ scope._span.set_attribute(
166
+ SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens
167
+ )
168
+ scope._span.set_attribute(
169
+ SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, input_tokens + output_tokens
170
+ )
115
171
  scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
116
172
 
117
173
  # Span Attributes for Tools
118
174
  if scope._tools:
119
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_NAME, scope._tools.get("function","")).get("name","")
120
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_CALL_ID, str(scope._tools.get("id","")))
121
- scope._span.set_attribute(SemanticConvention.GEN_AI_TOOL_ARGS, str(scope._tools.get("function","").get("arguments","")))
175
+ scope._span.set_attribute(
176
+ SemanticConvention.GEN_AI_TOOL_NAME, scope._tools.get("function", "")
177
+ ).get("name", "")
178
+ scope._span.set_attribute(
179
+ SemanticConvention.GEN_AI_TOOL_CALL_ID, str(scope._tools.get("id", ""))
180
+ )
181
+ scope._span.set_attribute(
182
+ SemanticConvention.GEN_AI_TOOL_ARGS,
183
+ str(scope._tools.get("function", "").get("arguments", "")),
184
+ )
122
185
 
123
186
  # Span Attributes for Content
124
187
  if capture_message_content:
125
188
  scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_PROMPT, prompt)
126
- scope._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse)
189
+ scope._span.set_attribute(
190
+ SemanticConvention.GEN_AI_CONTENT_COMPLETION, scope._llmresponse
191
+ )
127
192
 
128
193
  # To be removed one the change to span_attributes (from span events) is complete
129
194
  scope._span.add_event(
@@ -143,13 +208,36 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
143
208
 
144
209
  # Metrics
145
210
  if not disable_metrics:
146
- record_completion_metrics(metrics, SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT, SemanticConvention.GEN_AI_SYSTEM_PREMAI,
147
- scope._server_address, scope._server_port, request_model, scope._response_model, environment,
148
- application_name, scope._start_time, scope._end_time, input_tokens, output_tokens,
149
- cost, scope._tbt, scope._ttft)
211
+ record_completion_metrics(
212
+ metrics,
213
+ SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
214
+ SemanticConvention.GEN_AI_SYSTEM_PREMAI,
215
+ scope._server_address,
216
+ scope._server_port,
217
+ request_model,
218
+ scope._response_model,
219
+ environment,
220
+ application_name,
221
+ scope._start_time,
222
+ scope._end_time,
223
+ input_tokens,
224
+ output_tokens,
225
+ cost,
226
+ scope._tbt,
227
+ scope._ttft,
228
+ )
229
+
150
230
 
151
- def common_embedding_logic(scope, pricing_info, environment, application_name, metrics,
152
- capture_message_content, disable_metrics, version):
231
+ def common_embedding_logic(
232
+ scope,
233
+ pricing_info,
234
+ environment,
235
+ application_name,
236
+ metrics,
237
+ capture_message_content,
238
+ disable_metrics,
239
+ version,
240
+ ):
153
241
  """
154
242
  Process embedding request and generate Telemetry
155
243
  """
@@ -159,16 +247,36 @@ def common_embedding_logic(scope, pricing_info, environment, application_name, m
159
247
  cost = get_embed_model_cost(request_model, pricing_info, scope._input_tokens)
160
248
 
161
249
  # Common Span Attributes
162
- common_span_attributes(scope,
163
- SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING, SemanticConvention.GEN_AI_SYSTEM_PREMAI,
164
- scope._server_address, scope._server_port, request_model, scope._response_model,
165
- environment, application_name, False, scope._tbt, scope._ttft, version)
250
+ common_span_attributes(
251
+ scope,
252
+ SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING,
253
+ SemanticConvention.GEN_AI_SYSTEM_PREMAI,
254
+ scope._server_address,
255
+ scope._server_port,
256
+ request_model,
257
+ scope._response_model,
258
+ environment,
259
+ application_name,
260
+ False,
261
+ scope._tbt,
262
+ scope._ttft,
263
+ version,
264
+ )
166
265
 
167
266
  # Embedding-specific span attributes
168
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_ENCODING_FORMATS, [scope._kwargs.get("encoding_format", "float")])
169
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_USER, scope._kwargs.get("user", ""))
170
- scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens)
171
- scope._span.set_attribute(SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, scope._input_tokens)
267
+ scope._span.set_attribute(
268
+ SemanticConvention.GEN_AI_REQUEST_ENCODING_FORMATS,
269
+ [scope._kwargs.get("encoding_format", "float")],
270
+ )
271
+ scope._span.set_attribute(
272
+ SemanticConvention.GEN_AI_REQUEST_USER, scope._kwargs.get("user", "")
273
+ )
274
+ scope._span.set_attribute(
275
+ SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, scope._input_tokens
276
+ )
277
+ scope._span.set_attribute(
278
+ SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, scope._input_tokens
279
+ )
172
280
  scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
173
281
 
174
282
  # Span Attributes for Content
@@ -176,7 +284,9 @@ def common_embedding_logic(scope, pricing_info, environment, application_name, m
176
284
  scope._span.add_event(
177
285
  name=SemanticConvention.GEN_AI_CONTENT_PROMPT_EVENT,
178
286
  attributes={
179
- SemanticConvention.GEN_AI_CONTENT_PROMPT: str(scope._kwargs.get("input", "")),
287
+ SemanticConvention.GEN_AI_CONTENT_PROMPT: str(
288
+ scope._kwargs.get("input", "")
289
+ ),
180
290
  },
181
291
  )
182
292
 
@@ -184,21 +294,65 @@ def common_embedding_logic(scope, pricing_info, environment, application_name, m
184
294
 
185
295
  # Metrics
186
296
  if not disable_metrics:
187
- record_embedding_metrics(metrics, SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING, SemanticConvention.GEN_AI_SYSTEM_PREMAI,
188
- scope._server_address, scope._server_port, request_model, scope._response_model, environment,
189
- application_name, scope._start_time, scope._end_time, scope._input_tokens, cost)
297
+ record_embedding_metrics(
298
+ metrics,
299
+ SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING,
300
+ SemanticConvention.GEN_AI_SYSTEM_PREMAI,
301
+ scope._server_address,
302
+ scope._server_port,
303
+ request_model,
304
+ scope._response_model,
305
+ environment,
306
+ application_name,
307
+ scope._start_time,
308
+ scope._end_time,
309
+ scope._input_tokens,
310
+ cost,
311
+ )
190
312
 
191
- def process_streaming_chat_response(scope, pricing_info, environment, application_name, metrics,
192
- capture_message_content=False, disable_metrics=False, version=""):
313
+
314
+ def process_streaming_chat_response(
315
+ scope,
316
+ pricing_info,
317
+ environment,
318
+ application_name,
319
+ metrics,
320
+ capture_message_content=False,
321
+ disable_metrics=False,
322
+ version="",
323
+ ):
193
324
  """
194
325
  Process chat request and generate Telemetry
195
326
  """
196
- common_chat_logic(scope, pricing_info, environment, application_name, metrics,
197
- capture_message_content, disable_metrics, version, is_stream=True)
198
-
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):
327
+ common_chat_logic(
328
+ scope,
329
+ pricing_info,
330
+ environment,
331
+ application_name,
332
+ metrics,
333
+ capture_message_content,
334
+ disable_metrics,
335
+ version,
336
+ is_stream=True,
337
+ )
338
+
339
+
340
+ def process_chat_response(
341
+ response,
342
+ request_model,
343
+ pricing_info,
344
+ server_port,
345
+ server_address,
346
+ environment,
347
+ application_name,
348
+ metrics,
349
+ start_time,
350
+ span,
351
+ capture_message_content=False,
352
+ disable_metrics=False,
353
+ version="1.0.0",
354
+ **kwargs,
355
+ ):
202
356
  """
203
357
  Process chat request and generate Telemetry
204
358
  """
@@ -209,7 +363,9 @@ def process_chat_response(response, request_model, pricing_info, server_port, se
209
363
  scope._start_time = start_time
210
364
  scope._end_time = time.time()
211
365
  scope._span = span
212
- scope._llmresponse = str(response_dict.get("choices")[0].get("message").get("content"))
366
+ scope._llmresponse = str(
367
+ response_dict.get("choices")[0].get("message").get("content")
368
+ )
213
369
  scope._response_id = response_dict.get("additional_properties", {}).get("id")
214
370
  scope._response_model = response_dict.get("model")
215
371
  scope._input_tokens = response_dict.get("usage").get("prompt_tokens")
@@ -225,14 +381,37 @@ def process_chat_response(response, request_model, pricing_info, server_port, se
225
381
  else:
226
382
  scope._tools = None
227
383
 
228
- common_chat_logic(scope, pricing_info, environment, application_name, metrics,
229
- capture_message_content, disable_metrics, version, is_stream=False)
384
+ common_chat_logic(
385
+ scope,
386
+ pricing_info,
387
+ environment,
388
+ application_name,
389
+ metrics,
390
+ capture_message_content,
391
+ disable_metrics,
392
+ version,
393
+ is_stream=False,
394
+ )
230
395
 
231
396
  return response
232
397
 
233
- def process_embedding_response(response, request_model, pricing_info, server_port, server_address,
234
- environment, application_name, metrics, start_time, span, capture_message_content=False,
235
- disable_metrics=False, version="1.0.0", **kwargs):
398
+
399
+ def process_embedding_response(
400
+ response,
401
+ request_model,
402
+ pricing_info,
403
+ server_port,
404
+ server_address,
405
+ environment,
406
+ application_name,
407
+ metrics,
408
+ start_time,
409
+ span,
410
+ capture_message_content=False,
411
+ disable_metrics=False,
412
+ version="1.0.0",
413
+ **kwargs,
414
+ ):
236
415
  """
237
416
  Process embedding request and generate Telemetry
238
417
  """
@@ -250,7 +429,15 @@ def process_embedding_response(response, request_model, pricing_info, server_por
250
429
  scope._server_address, scope._server_port = server_address, server_port
251
430
  scope._kwargs = kwargs
252
431
 
253
- common_embedding_logic(scope, pricing_info, environment, application_name, metrics,
254
- capture_message_content, disable_metrics, version)
432
+ common_embedding_logic(
433
+ scope,
434
+ pricing_info,
435
+ environment,
436
+ application_name,
437
+ metrics,
438
+ capture_message_content,
439
+ disable_metrics,
440
+ version,
441
+ )
255
442
 
256
443
  return response