openlit 1.33.18__py3-none-any.whl → 1.33.20__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 (80) hide show
  1. openlit/__helpers.py +11 -41
  2. openlit/__init__.py +3 -3
  3. openlit/evals/utils.py +7 -7
  4. openlit/guard/utils.py +7 -7
  5. openlit/instrumentation/ag2/ag2.py +24 -24
  6. openlit/instrumentation/ai21/ai21.py +3 -3
  7. openlit/instrumentation/ai21/async_ai21.py +3 -3
  8. openlit/instrumentation/ai21/utils.py +59 -59
  9. openlit/instrumentation/anthropic/anthropic.py +2 -2
  10. openlit/instrumentation/anthropic/async_anthropic.py +2 -2
  11. openlit/instrumentation/anthropic/utils.py +34 -34
  12. openlit/instrumentation/assemblyai/assemblyai.py +24 -24
  13. openlit/instrumentation/astra/astra.py +3 -3
  14. openlit/instrumentation/astra/async_astra.py +3 -3
  15. openlit/instrumentation/astra/utils.py +39 -39
  16. openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +10 -10
  17. openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +10 -10
  18. openlit/instrumentation/azure_ai_inference/utils.py +38 -38
  19. openlit/instrumentation/bedrock/__init__.py +2 -1
  20. openlit/instrumentation/bedrock/bedrock.py +32 -214
  21. openlit/instrumentation/bedrock/utils.py +252 -0
  22. openlit/instrumentation/chroma/chroma.py +57 -57
  23. openlit/instrumentation/cohere/async_cohere.py +88 -88
  24. openlit/instrumentation/cohere/cohere.py +88 -88
  25. openlit/instrumentation/controlflow/controlflow.py +15 -15
  26. openlit/instrumentation/crawl4ai/async_crawl4ai.py +14 -14
  27. openlit/instrumentation/crawl4ai/crawl4ai.py +14 -14
  28. openlit/instrumentation/crewai/crewai.py +22 -22
  29. openlit/instrumentation/dynamiq/dynamiq.py +19 -19
  30. openlit/instrumentation/elevenlabs/async_elevenlabs.py +24 -25
  31. openlit/instrumentation/elevenlabs/elevenlabs.py +23 -25
  32. openlit/instrumentation/embedchain/embedchain.py +15 -15
  33. openlit/instrumentation/firecrawl/firecrawl.py +10 -10
  34. openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +33 -33
  35. openlit/instrumentation/google_ai_studio/google_ai_studio.py +33 -33
  36. openlit/instrumentation/gpt4all/gpt4all.py +78 -78
  37. openlit/instrumentation/gpu/__init__.py +8 -8
  38. openlit/instrumentation/groq/async_groq.py +74 -74
  39. openlit/instrumentation/groq/groq.py +74 -74
  40. openlit/instrumentation/haystack/haystack.py +6 -6
  41. openlit/instrumentation/julep/async_julep.py +14 -14
  42. openlit/instrumentation/julep/julep.py +14 -14
  43. openlit/instrumentation/langchain/async_langchain.py +39 -39
  44. openlit/instrumentation/langchain/langchain.py +39 -39
  45. openlit/instrumentation/letta/letta.py +26 -26
  46. openlit/instrumentation/litellm/async_litellm.py +94 -94
  47. openlit/instrumentation/litellm/litellm.py +94 -94
  48. openlit/instrumentation/llamaindex/llamaindex.py +7 -7
  49. openlit/instrumentation/mem0/mem0.py +13 -13
  50. openlit/instrumentation/milvus/milvus.py +47 -47
  51. openlit/instrumentation/mistral/async_mistral.py +88 -88
  52. openlit/instrumentation/mistral/mistral.py +88 -88
  53. openlit/instrumentation/multion/async_multion.py +21 -21
  54. openlit/instrumentation/multion/multion.py +21 -21
  55. openlit/instrumentation/ollama/async_ollama.py +3 -3
  56. openlit/instrumentation/ollama/ollama.py +3 -3
  57. openlit/instrumentation/ollama/utils.py +50 -50
  58. openlit/instrumentation/openai/async_openai.py +225 -225
  59. openlit/instrumentation/openai/openai.py +225 -225
  60. openlit/instrumentation/openai_agents/openai_agents.py +11 -11
  61. openlit/instrumentation/phidata/phidata.py +15 -15
  62. openlit/instrumentation/pinecone/pinecone.py +43 -43
  63. openlit/instrumentation/premai/premai.py +86 -86
  64. openlit/instrumentation/qdrant/async_qdrant.py +95 -95
  65. openlit/instrumentation/qdrant/qdrant.py +99 -99
  66. openlit/instrumentation/reka/async_reka.py +33 -33
  67. openlit/instrumentation/reka/reka.py +33 -33
  68. openlit/instrumentation/together/async_together.py +90 -90
  69. openlit/instrumentation/together/together.py +90 -90
  70. openlit/instrumentation/transformers/transformers.py +26 -26
  71. openlit/instrumentation/vertexai/async_vertexai.py +64 -64
  72. openlit/instrumentation/vertexai/vertexai.py +64 -64
  73. openlit/instrumentation/vllm/vllm.py +24 -24
  74. openlit/otel/metrics.py +11 -11
  75. openlit/semcov/__init__.py +3 -3
  76. {openlit-1.33.18.dist-info → openlit-1.33.20.dist-info}/METADATA +8 -8
  77. openlit-1.33.20.dist-info/RECORD +131 -0
  78. {openlit-1.33.18.dist-info → openlit-1.33.20.dist-info}/WHEEL +1 -1
  79. openlit-1.33.18.dist-info/RECORD +0 -130
  80. {openlit-1.33.18.dist-info → openlit-1.33.20.dist-info}/LICENSE +0 -0
openlit/__helpers.py CHANGED
@@ -12,7 +12,7 @@ import requests
12
12
  from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
13
13
  from opentelemetry.trace import Status, StatusCode
14
14
  from opentelemetry._events import Event
15
- from openlit.semcov import SemanticConvetion
15
+ from openlit.semcov import SemanticConvention
16
16
 
17
17
  # Set up logging
18
18
  logger = logging.getLogger(__name__)
@@ -176,12 +176,12 @@ def create_metrics_attributes(
176
176
  TELEMETRY_SDK_NAME: 'openlit',
177
177
  SERVICE_NAME: service_name,
178
178
  DEPLOYMENT_ENVIRONMENT: deployment_environment,
179
- SemanticConvetion.GEN_AI_OPERATION: operation,
180
- SemanticConvetion.GEN_AI_SYSTEM: system,
181
- SemanticConvetion.GEN_AI_REQUEST_MODEL: request_model,
182
- SemanticConvetion.SERVER_ADDRESS: server_address,
183
- SemanticConvetion.SERVER_PORT: server_port,
184
- SemanticConvetion.GEN_AI_RESPONSE_MODEL: response_model
179
+ SemanticConvention.GEN_AI_OPERATION: operation,
180
+ SemanticConvention.GEN_AI_SYSTEM: system,
181
+ SemanticConvention.GEN_AI_REQUEST_MODEL: request_model,
182
+ SemanticConvention.SERVER_ADDRESS: server_address,
183
+ SemanticConvention.SERVER_PORT: server_port,
184
+ SemanticConvention.GEN_AI_RESPONSE_MODEL: response_model
185
185
  }
186
186
 
187
187
  def set_server_address_and_port(client_instance: Any,
@@ -237,27 +237,21 @@ def extract_and_format_input(messages):
237
237
  them into fixed roles like 'user', 'assistant', 'system', 'tool'.
238
238
  """
239
239
 
240
- fixed_roles = ['user', 'assistant', 'system', 'tool'] # Ensure these are your fixed keys
241
- # Initialize the dictionary with fixed keys and empty structures
240
+ fixed_roles = ['user', 'assistant', 'system', 'tool', 'developer']
242
241
  formatted_messages = {role_key: {'role': '', 'content': ''} for role_key in fixed_roles}
243
242
 
244
243
  for message in messages:
245
- # Normalize the message structure
246
244
  message = response_as_dict(message)
247
245
 
248
- # Extract role and content
249
246
  role = message.get('role')
250
247
  if role not in fixed_roles:
251
- continue # Skip any role not in our predefined roles
248
+ continue
252
249
 
253
250
  content = message.get('content', '')
254
251
 
255
- # Prepare content as a string
252
+ # Prepare content as a string, handling both list and str
256
253
  if isinstance(content, list):
257
- content_str = ", ".join(
258
- f'{item.get("type", "text")}: {extract_text_from_item(item)}'
259
- for item in content
260
- )
254
+ content_str = ", ".join(str(item) for item in content)
261
255
  else:
262
256
  content_str = content
263
257
 
@@ -272,30 +266,6 @@ def extract_and_format_input(messages):
272
266
 
273
267
  return formatted_messages
274
268
 
275
- def extract_text_from_item(item):
276
- """
277
- Extract text from inpit message
278
- """
279
-
280
- #pylint: disable=no-else-return
281
- if item.get('type') == 'text':
282
- return item.get('text', '')
283
- elif item.get('type') == 'image':
284
- # Handle image content specifically checking for 'url' or 'base64'
285
- source = item.get('source', {})
286
- if isinstance(source, dict):
287
- if source.get('type') == 'base64':
288
- # Return the actual base64 data if present
289
- return source.get('data', '[Missing base64 data]')
290
- elif source.get('type') == 'url':
291
- return source.get('url', '[Missing URL]')
292
- elif item.get('type') == 'image_url':
293
- # New format: Handle the 'image_url' type
294
- image_url = item.get('image_url', {})
295
- if isinstance(image_url, dict):
296
- return image_url.get('url', '[Missing image URL]')
297
- return ''
298
-
299
269
  # To be removed one the change to log events (from span events) is complete
300
270
  def concatenate_all_contents(formatted_messages):
301
271
  """
openlit/__init__.py CHANGED
@@ -18,7 +18,7 @@ import requests
18
18
  from opentelemetry import trace as t
19
19
  from opentelemetry.trace import SpanKind, Status, StatusCode, Span
20
20
  from opentelemetry.sdk.resources import SERVICE_NAME, DEPLOYMENT_ENVIRONMENT
21
- from openlit.semcov import SemanticConvetion
21
+ from openlit.semcov import SemanticConvention
22
22
  from openlit.otel.tracing import setup_tracing
23
23
  from openlit.otel.metrics import setup_meter
24
24
  from openlit.otel.events import setup_events
@@ -573,7 +573,7 @@ def trace(wrapped):
573
573
  try:
574
574
  response = wrapped(*args, **kwargs)
575
575
  span.set_attribute(
576
- SemanticConvetion.GEN_AI_CONTENT_COMPLETION, response or ""
576
+ SemanticConvention.GEN_AI_CONTENT_COMPLETION, response or ""
577
577
  )
578
578
  span.set_status(Status(StatusCode.OK))
579
579
  except Exception as e:
@@ -632,7 +632,7 @@ class TracedSpan:
632
632
  result: The result to be set as an attribute on the span.
633
633
  """
634
634
 
635
- self._span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION, result)
635
+ self._span.set_attribute(SemanticConvention.GEN_AI_CONTENT_COMPLETION, result)
636
636
 
637
637
  def set_metadata(self, metadata: Dict):
638
638
  """
openlit/evals/utils.py CHANGED
@@ -10,7 +10,7 @@ from opentelemetry.metrics import get_meter
10
10
  from opentelemetry.sdk.resources import TELEMETRY_SDK_NAME
11
11
  from anthropic import Anthropic
12
12
  from openai import OpenAI
13
- from openlit.semcov import SemanticConvetion
13
+ from openlit.semcov import SemanticConvention
14
14
 
15
15
  # Initialize logger for logging potential issues and operations
16
16
  logger = logging.getLogger(__name__)
@@ -238,7 +238,7 @@ def eval_metrics():
238
238
  )
239
239
 
240
240
  guard_requests = meter.create_counter(
241
- name=SemanticConvetion.EVAL_REQUESTS,
241
+ name=SemanticConvention.EVAL_REQUESTS,
242
242
  description="Counter for evaluation requests",
243
243
  unit="1"
244
244
  )
@@ -262,14 +262,14 @@ def eval_metric_attributes(verdict, score, validator, classification, explanatio
262
262
  return {
263
263
  TELEMETRY_SDK_NAME:
264
264
  "openlit",
265
- SemanticConvetion.EVAL_VERDICT:
265
+ SemanticConvention.EVAL_VERDICT:
266
266
  verdict,
267
- SemanticConvetion.EVAL_SCORE:
267
+ SemanticConvention.EVAL_SCORE:
268
268
  score,
269
- SemanticConvetion.EVAL_VALIDATOR:
269
+ SemanticConvention.EVAL_VALIDATOR:
270
270
  validator,
271
- SemanticConvetion.EVAL_CLASSIFICATION:
271
+ SemanticConvention.EVAL_CLASSIFICATION:
272
272
  classification,
273
- SemanticConvetion.EVAL_EXPLANATION:
273
+ SemanticConvention.EVAL_EXPLANATION:
274
274
  explanation,
275
275
  }
openlit/guard/utils.py CHANGED
@@ -11,7 +11,7 @@ from opentelemetry.metrics import get_meter
11
11
  from opentelemetry.sdk.resources import TELEMETRY_SDK_NAME
12
12
  from anthropic import Anthropic
13
13
  from openai import OpenAI
14
- from openlit.semcov import SemanticConvetion
14
+ from openlit.semcov import SemanticConvention
15
15
 
16
16
  # Initialize logger for logging potential issues and operations
17
17
  logger = logging.getLogger(__name__)
@@ -202,7 +202,7 @@ def guard_metrics():
202
202
  )
203
203
 
204
204
  guard_requests = meter.create_counter(
205
- name=SemanticConvetion.GUARD_REQUESTS,
205
+ name=SemanticConvention.GUARD_REQUESTS,
206
206
  description="Counter for Guard requests",
207
207
  unit="1"
208
208
  )
@@ -224,9 +224,9 @@ def guard_metric_attributes(verdict, score, validator, classification, explanati
224
224
  """
225
225
  return {
226
226
  TELEMETRY_SDK_NAME: "openlit",
227
- SemanticConvetion.GUARD_VERDICT: verdict,
228
- SemanticConvetion.GUARD_SCORE: score,
229
- SemanticConvetion.GUARD_VALIDATOR: validator,
230
- SemanticConvetion.GUARD_CLASSIFICATION: classification,
231
- SemanticConvetion.GUARD_EXPLANATION: explanation,
227
+ SemanticConvention.GUARD_VERDICT: verdict,
228
+ SemanticConvention.GUARD_SCORE: score,
229
+ SemanticConvention.GUARD_VALIDATOR: validator,
230
+ SemanticConvention.GUARD_CLASSIFICATION: classification,
231
+ SemanticConvention.GUARD_EXPLANATION: explanation,
232
232
  }
@@ -11,7 +11,7 @@ from openlit.__helpers import (
11
11
  get_chat_model_cost,
12
12
  otel_event,
13
13
  )
14
- from openlit.semcov import SemanticConvetion
14
+ from openlit.semcov import SemanticConvention
15
15
 
16
16
  # Initialize logger for logging potential issues and operations
17
17
  logger = logging.getLogger(__name__)
@@ -29,17 +29,17 @@ def set_span_attributes(span, version, operation_name, environment,
29
29
 
30
30
  # Set Span attributes (OTel Semconv)
31
31
  span.set_attribute(TELEMETRY_SDK_NAME, 'openlit')
32
- span.set_attribute(SemanticConvetion.GEN_AI_OPERATION, operation_name)
33
- span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM, SemanticConvetion.GEN_AI_SYSTEM_AG2)
34
- span.set_attribute(SemanticConvetion.GEN_AI_AGENT_NAME, AGENT_NAME)
35
- span.set_attribute(SemanticConvetion.SERVER_ADDRESS, server_address)
36
- span.set_attribute(SemanticConvetion.SERVER_PORT, server_port)
37
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL, request_model)
32
+ span.set_attribute(SemanticConvention.GEN_AI_OPERATION, operation_name)
33
+ span.set_attribute(SemanticConvention.GEN_AI_SYSTEM, SemanticConvention.GEN_AI_SYSTEM_AG2)
34
+ span.set_attribute(SemanticConvention.GEN_AI_AGENT_NAME, AGENT_NAME)
35
+ span.set_attribute(SemanticConvention.SERVER_ADDRESS, server_address)
36
+ span.set_attribute(SemanticConvention.SERVER_PORT, server_port)
37
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL, request_model)
38
38
 
39
39
  # Set Span attributes (Extras)
40
40
  span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
41
41
  span.set_attribute(SERVICE_NAME, application_name)
42
- span.set_attribute(SemanticConvetion.GEN_AI_SDK_VERSION, version)
42
+ span.set_attribute(SemanticConvention.GEN_AI_SDK_VERSION, version)
43
43
 
44
44
  def calculate_tokens_and_cost(response, request_model, pricing_info):
45
45
  """
@@ -64,13 +64,13 @@ def emit_events(response, event_provider, capture_message_content):
64
64
  """
65
65
  for chat in response.chat_history:
66
66
  event_type = (
67
- SemanticConvetion.GEN_AI_CHOICE if chat['role'] == 'user'
68
- else SemanticConvetion.GEN_AI_USER_MESSAGE
67
+ SemanticConvention.GEN_AI_CHOICE if chat['role'] == 'user'
68
+ else SemanticConvention.GEN_AI_USER_MESSAGE
69
69
  )
70
70
  choice_event = otel_event(
71
71
  name=event_type,
72
72
  attributes={
73
- SemanticConvetion.GEN_AI_SYSTEM: SemanticConvetion.GEN_AI_SYSTEM_AG2
73
+ SemanticConvention.GEN_AI_SYSTEM: SemanticConvention.GEN_AI_SYSTEM_AG2
74
74
  },
75
75
  body={
76
76
  'index': response.chat_history.index(chat),
@@ -97,7 +97,7 @@ def conversable_agent(version, environment, application_name,
97
97
  SYSTEM_MESSAGE = kwargs.get('system_message', '')
98
98
  MODEL_AND_NAME_SET = True
99
99
 
100
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CREATE_AGENT} {AGENT_NAME}'
100
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CREATE_AGENT} {AGENT_NAME}'
101
101
 
102
102
  with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
103
103
  try:
@@ -105,11 +105,11 @@ def conversable_agent(version, environment, application_name,
105
105
  response = wrapped(*args, **kwargs)
106
106
  end_time = time.time()
107
107
 
108
- set_span_attributes(span, version, SemanticConvetion.GEN_AI_OPERATION_TYPE_CREATE_AGENT,
108
+ set_span_attributes(span, version, SemanticConvention.GEN_AI_OPERATION_TYPE_CREATE_AGENT,
109
109
  environment, application_name, server_address, server_port, REQUEST_MODEL)
110
- span.set_attribute(SemanticConvetion.GEN_AI_AGENT_DESCRIPTION, SYSTEM_MESSAGE)
111
- span.set_attribute(SemanticConvetion.GEN_AI_RESPONSE_MODEL, REQUEST_MODEL)
112
- span.set_attribute(SemanticConvetion.GEN_AI_SERVER_TTFT, end_time - start_time)
110
+ span.set_attribute(SemanticConvention.GEN_AI_AGENT_DESCRIPTION, SYSTEM_MESSAGE)
111
+ span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_MODEL, REQUEST_MODEL)
112
+ span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT, end_time - start_time)
113
113
 
114
114
  span.set_status(Status(StatusCode.OK))
115
115
 
@@ -130,7 +130,7 @@ def agent_run(version, environment, application_name,
130
130
  def wrapper(wrapped, instance, args, kwargs):
131
131
  server_address, server_port = '127.0.0.1', 80
132
132
 
133
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_EXECUTE_AGENT_TASK} {AGENT_NAME}'
133
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_EXECUTE_AGENT_TASK} {AGENT_NAME}'
134
134
 
135
135
  with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
136
136
  try:
@@ -141,14 +141,14 @@ def agent_run(version, environment, application_name,
141
141
  input_tokens, output_tokens, cost = calculate_tokens_and_cost(response, REQUEST_MODEL, pricing_info)
142
142
  response_model = list(response.cost.get('usage_including_cached_inference', {}).keys())[1]
143
143
 
144
- set_span_attributes(span, version, SemanticConvetion.GEN_AI_OPERATION_TYPE_EXECUTE_AGENT_TASK,
144
+ set_span_attributes(span, version, SemanticConvention.GEN_AI_OPERATION_TYPE_EXECUTE_AGENT_TASK,
145
145
  environment, application_name, server_address, server_port, REQUEST_MODEL)
146
- span.set_attribute(SemanticConvetion.GEN_AI_RESPONSE_MODEL, response_model)
147
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
148
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
149
- span.set_attribute(SemanticConvetion.GEN_AI_CLIENT_TOKEN_USAGE, input_tokens + output_tokens)
150
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST, cost)
151
- span.set_attribute(SemanticConvetion.GEN_AI_SERVER_TTFT, end_time - start_time)
146
+ span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_MODEL, response_model)
147
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
148
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
149
+ span.set_attribute(SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE, input_tokens + output_tokens)
150
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
151
+ span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT, end_time - start_time)
152
152
 
153
153
  emit_events(response, event_provider, capture_message_content)
154
154
  span.set_status(Status(StatusCode.OK))
@@ -16,7 +16,7 @@ from openlit.instrumentation.ai21.utils import (
16
16
  process_chat_rag_response
17
17
  )
18
18
 
19
- from openlit.semcov import SemanticConvetion
19
+ from openlit.semcov import SemanticConvention
20
20
 
21
21
  # Initialize logger for logging potential issues and operations
22
22
  logger = logging.getLogger(__name__)
@@ -113,7 +113,7 @@ def chat(version, environment, application_name,
113
113
  server_address, server_port = set_server_address_and_port(instance, 'api.ai21.com', 443)
114
114
  request_model = kwargs.get('model', 'jamba-1.5-mini')
115
115
 
116
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
116
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
117
117
 
118
118
  # pylint: disable=no-else-return
119
119
  if streaming:
@@ -163,7 +163,7 @@ def chat_rag(version, environment, application_name,
163
163
  server_address, server_port = set_server_address_and_port(instance, 'api.ai21.com', 443)
164
164
  request_model = kwargs.get('model', 'jamba-1.5-mini')
165
165
 
166
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
166
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
167
167
 
168
168
  with tracer.start_as_current_span(span_name, kind= SpanKind.CLIENT) as span:
169
169
  start_time = time.time()
@@ -16,7 +16,7 @@ from openlit.instrumentation.ai21.utils import (
16
16
  process_chat_rag_response
17
17
  )
18
18
 
19
- from openlit.semcov import SemanticConvetion
19
+ from openlit.semcov import SemanticConvention
20
20
 
21
21
  # Initialize logger for logging potential issues and operations
22
22
  logger = logging.getLogger(__name__)
@@ -113,7 +113,7 @@ def async_chat(version, environment, application_name,
113
113
  server_address, server_port = set_server_address_and_port(instance, 'api.ai21.com', 443)
114
114
  request_model = kwargs.get('model', 'jamba-1.5-mini')
115
115
 
116
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
116
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
117
117
 
118
118
  # pylint: disable=no-else-return
119
119
  if streaming:
@@ -163,7 +163,7 @@ def async_chat_rag(version, environment, application_name,
163
163
  server_address, server_port = set_server_address_and_port(instance, 'api.ai21.com', 443)
164
164
  request_model = kwargs.get('model', 'jamba-1.5-mini')
165
165
 
166
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
166
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
167
167
 
168
168
  with tracer.start_as_current_span(span_name, kind= SpanKind.CLIENT) as span:
169
169
  start_time = time.time()
@@ -19,7 +19,7 @@ from openlit.__helpers import (
19
19
  otel_event,
20
20
  concatenate_all_contents
21
21
  )
22
- from openlit.semcov import SemanticConvetion
22
+ from openlit.semcov import SemanticConvention
23
23
 
24
24
  def setup_common_span_attributes(span, request_model, kwargs, tokens,
25
25
  server_port, server_address, environment,
@@ -30,32 +30,32 @@ def setup_common_span_attributes(span, request_model, kwargs, tokens,
30
30
 
31
31
  # Base attributes from SDK and operation settings.
32
32
  span.set_attribute(TELEMETRY_SDK_NAME, 'openlit')
33
- span.set_attribute(SemanticConvetion.GEN_AI_OPERATION, SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT)
34
- span.set_attribute(SemanticConvetion.GEN_AI_SYSTEM, SemanticConvetion.GEN_AI_SYSTEM_AI21)
35
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MODEL, request_model)
36
- span.set_attribute(SemanticConvetion.SERVER_PORT, server_port)
37
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_SEED, kwargs.get('seed', ''))
38
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_FREQUENCY_PENALTY, kwargs.get('frequency_penalty', 0.0))
39
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get('max_tokens', -1))
40
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_PRESENCE_PENALTY, kwargs.get('presence_penalty', 0.0))
41
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_STOP_SEQUENCES, kwargs.get('stop', []))
42
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TEMPERATURE, kwargs.get('temperature', 0.4))
43
- span.set_attribute(SemanticConvetion.GEN_AI_REQUEST_TOP_P, kwargs.get('top_p', 1.0))
33
+ span.set_attribute(SemanticConvention.GEN_AI_OPERATION, SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT)
34
+ span.set_attribute(SemanticConvention.GEN_AI_SYSTEM, SemanticConvention.GEN_AI_SYSTEM_AI21)
35
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL, request_model)
36
+ span.set_attribute(SemanticConvention.SERVER_PORT, server_port)
37
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_SEED, kwargs.get('seed', ''))
38
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_FREQUENCY_PENALTY, kwargs.get('frequency_penalty', 0.0))
39
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get('max_tokens', -1))
40
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_PRESENCE_PENALTY, kwargs.get('presence_penalty', 0.0))
41
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_STOP_SEQUENCES, kwargs.get('stop', []))
42
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE, kwargs.get('temperature', 0.4))
43
+ span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_P, kwargs.get('top_p', 1.0))
44
44
 
45
45
  # Add token-related attributes if available.
46
46
  if 'finish_reason' in tokens:
47
- span.set_attribute(SemanticConvetion.GEN_AI_RESPONSE_FINISH_REASON, [tokens['finish_reason']])
47
+ span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_FINISH_REASON, [tokens['finish_reason']])
48
48
  if 'response_id' in tokens:
49
- span.set_attribute(SemanticConvetion.GEN_AI_RESPONSE_ID, tokens['response_id'])
49
+ span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_ID, tokens['response_id'])
50
50
  if 'input_tokens' in tokens:
51
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_INPUT_TOKENS, tokens['input_tokens'])
51
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS, tokens['input_tokens'])
52
52
  if 'output_tokens' in tokens:
53
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_OUTPUT_TOKENS, tokens['output_tokens'])
53
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, tokens['output_tokens'])
54
54
  if 'total_tokens' in tokens:
55
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS, tokens['total_tokens'])
55
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_TOTAL_TOKENS, tokens['total_tokens'])
56
56
 
57
- span.set_attribute(SemanticConvetion.GEN_AI_RESPONSE_MODEL, request_model)
58
- span.set_attribute(SemanticConvetion.SERVER_ADDRESS, server_address)
57
+ span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_MODEL, request_model)
58
+ span.set_attribute(SemanticConvention.SERVER_ADDRESS, server_address)
59
59
  # Environment and service identifiers.
60
60
  span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
61
61
  span.set_attribute(SERVICE_NAME, application_name)
@@ -73,8 +73,8 @@ def record_common_metrics(metrics, application_name, environment, request_model,
73
73
  attributes = create_metrics_attributes(
74
74
  service_name=application_name,
75
75
  deployment_environment=environment,
76
- operation=SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT,
77
- system=SemanticConvetion.GEN_AI_SYSTEM_AI21,
76
+ operation=SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
77
+ system=SemanticConvention.GEN_AI_SYSTEM_AI21,
78
78
  request_model=request_model,
79
79
  server_address=server_address,
80
80
  server_port=server_port,
@@ -121,15 +121,15 @@ def emit_common_events(event_provider, choices, finish_reason, llmresponse, form
121
121
  }
122
122
  })
123
123
  event = otel_event(
124
- name=SemanticConvetion.GEN_AI_CHOICE,
125
- attributes={SemanticConvetion.GEN_AI_SYSTEM: SemanticConvetion.GEN_AI_SYSTEM_AI21},
124
+ name=SemanticConvention.GEN_AI_CHOICE,
125
+ attributes={SemanticConvention.GEN_AI_SYSTEM: SemanticConvention.GEN_AI_SYSTEM_AI21},
126
126
  body=choice_event_body
127
127
  )
128
128
  event_provider.emit(event)
129
129
  else:
130
130
  event = otel_event(
131
- name=SemanticConvetion.GEN_AI_CHOICE,
132
- attributes={SemanticConvetion.GEN_AI_SYSTEM: SemanticConvetion.GEN_AI_SYSTEM_AI21},
131
+ name=SemanticConvention.GEN_AI_CHOICE,
132
+ attributes={SemanticConvention.GEN_AI_SYSTEM: SemanticConvention.GEN_AI_SYSTEM_AI21},
133
133
  body=choice_event_body
134
134
  )
135
135
  event_provider.emit(event)
@@ -144,8 +144,8 @@ def emit_common_events(event_provider, choices, finish_reason, llmresponse, form
144
144
  }
145
145
  }
146
146
  event = otel_event(
147
- name=SemanticConvetion.GEN_AI_CHOICE,
148
- attributes={SemanticConvetion.GEN_AI_SYSTEM: SemanticConvetion.GEN_AI_SYSTEM_AI21},
147
+ name=SemanticConvention.GEN_AI_CHOICE,
148
+ attributes={SemanticConvention.GEN_AI_SYSTEM: SemanticConvention.GEN_AI_SYSTEM_AI21},
149
149
  body=choice_event_body
150
150
  )
151
151
  event_provider.emit(event)
@@ -175,8 +175,8 @@ def emit_common_events(event_provider, choices, finish_reason, llmresponse, form
175
175
  if tool_calls:
176
176
  event_body['id'] = tool_calls[0].get('id', '')
177
177
  event = otel_event(
178
- name=getattr(SemanticConvetion, f'GEN_AI_{role.upper()}_MESSAGE'),
179
- attributes={SemanticConvetion.GEN_AI_SYSTEM: SemanticConvetion.GEN_AI_SYSTEM_AI21},
178
+ name=getattr(SemanticConvention, f'GEN_AI_{role.upper()}_MESSAGE'),
179
+ attributes={SemanticConvention.GEN_AI_SYSTEM: SemanticConvention.GEN_AI_SYSTEM_AI21},
180
180
  body=event_body
181
181
  )
182
182
  event_provider.emit(event)
@@ -233,13 +233,13 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
233
233
  'total_tokens': scope._input_tokens + scope._output_tokens,
234
234
  }
235
235
  extra_attrs = {
236
- SemanticConvetion.GEN_AI_REQUEST_IS_STREAM: is_stream,
237
- SemanticConvetion.GEN_AI_CLIENT_TOKEN_USAGE: scope._input_tokens + scope._output_tokens,
238
- SemanticConvetion.GEN_AI_USAGE_COST: cost,
239
- SemanticConvetion.GEN_AI_SERVER_TBT: scope._tbt,
240
- SemanticConvetion.GEN_AI_SERVER_TTFT: scope._ttft,
241
- SemanticConvetion.GEN_AI_SDK_VERSION: version,
242
- SemanticConvetion.GEN_AI_OUTPUT_TYPE: 'text' if isinstance(scope._llmresponse, str) else 'json'
236
+ SemanticConvention.GEN_AI_REQUEST_IS_STREAM: is_stream,
237
+ SemanticConvention.GEN_AI_CLIENT_TOKEN_USAGE: scope._input_tokens + scope._output_tokens,
238
+ SemanticConvention.GEN_AI_USAGE_COST: cost,
239
+ SemanticConvention.GEN_AI_SERVER_TBT: scope._tbt,
240
+ SemanticConvention.GEN_AI_SERVER_TTFT: scope._ttft,
241
+ SemanticConvention.GEN_AI_SDK_VERSION: version,
242
+ SemanticConvention.GEN_AI_OUTPUT_TYPE: 'text' if isinstance(scope._llmresponse, str) else 'json'
243
243
  }
244
244
  # Set span attributes.
245
245
  setup_common_span_attributes(scope._span, request_model, scope._kwargs, tokens,
@@ -249,12 +249,12 @@ def common_chat_logic(scope, pricing_info, environment, application_name, metric
249
249
  # Optionally add events capturing the prompt and completion.
250
250
  if capture_message_content:
251
251
  scope._span.add_event(
252
- name=SemanticConvetion.GEN_AI_CONTENT_PROMPT_EVENT,
253
- attributes={SemanticConvetion.GEN_AI_CONTENT_PROMPT: prompt},
252
+ name=SemanticConvention.GEN_AI_CONTENT_PROMPT_EVENT,
253
+ attributes={SemanticConvention.GEN_AI_CONTENT_PROMPT: prompt},
254
254
  )
255
255
  scope._span.add_event(
256
- name=SemanticConvetion.GEN_AI_CONTENT_COMPLETION_EVENT,
257
- attributes={SemanticConvetion.GEN_AI_CONTENT_COMPLETION: scope._llmresponse},
256
+ name=SemanticConvention.GEN_AI_CONTENT_COMPLETION_EVENT,
257
+ attributes={SemanticConvention.GEN_AI_CONTENT_COMPLETION: scope._llmresponse},
258
258
  )
259
259
 
260
260
  # Emit events for each choice and message role.
@@ -336,15 +336,15 @@ def process_chat_rag_response(response, request_model, pricing_info, server_port
336
336
  # Create tokens dict and RAG-specific extra attributes.
337
337
  tokens = {'response_id': response_dict.get('id'), 'input_tokens': input_tokens}
338
338
  extra_attrs = {
339
- SemanticConvetion.GEN_AI_REQUEST_IS_STREAM: False,
340
- SemanticConvetion.GEN_AI_SERVER_TTFT: end_time - start_time,
341
- SemanticConvetion.GEN_AI_SDK_VERSION: version,
342
- SemanticConvetion.GEN_AI_RAG_MAX_SEGMENTS: kwargs.get('max_segments', -1),
343
- SemanticConvetion.GEN_AI_RAG_STRATEGY: kwargs.get('retrieval_strategy', 'segments'),
344
- SemanticConvetion.GEN_AI_RAG_SIMILARITY_THRESHOLD: kwargs.get('retrieval_similarity_threshold', -1),
345
- SemanticConvetion.GEN_AI_RAG_MAX_NEIGHBORS: kwargs.get('max_neighbors', -1),
346
- SemanticConvetion.GEN_AI_RAG_FILE_IDS: str(kwargs.get('file_ids', '')),
347
- SemanticConvetion.GEN_AI_RAG_DOCUMENTS_PATH: kwargs.get('path', '')
339
+ SemanticConvention.GEN_AI_REQUEST_IS_STREAM: False,
340
+ SemanticConvention.GEN_AI_SERVER_TTFT: end_time - start_time,
341
+ SemanticConvention.GEN_AI_SDK_VERSION: version,
342
+ SemanticConvention.GEN_AI_RAG_MAX_SEGMENTS: kwargs.get('max_segments', -1),
343
+ SemanticConvention.GEN_AI_RAG_STRATEGY: kwargs.get('retrieval_strategy', 'segments'),
344
+ SemanticConvention.GEN_AI_RAG_SIMILARITY_THRESHOLD: kwargs.get('retrieval_similarity_threshold', -1),
345
+ SemanticConvention.GEN_AI_RAG_MAX_NEIGHBORS: kwargs.get('max_neighbors', -1),
346
+ SemanticConvention.GEN_AI_RAG_FILE_IDS: str(kwargs.get('file_ids', '')),
347
+ SemanticConvention.GEN_AI_RAG_DOCUMENTS_PATH: kwargs.get('path', '')
348
348
  }
349
349
  # Set common span attributes.
350
350
  setup_common_span_attributes(span, request_model, kwargs, tokens,
@@ -354,8 +354,8 @@ def process_chat_rag_response(response, request_model, pricing_info, server_port
354
354
  # Record the prompt event if requested.
355
355
  if capture_message_content:
356
356
  span.add_event(
357
- name=SemanticConvetion.GEN_AI_CONTENT_PROMPT_EVENT,
358
- attributes={SemanticConvetion.GEN_AI_CONTENT_PROMPT: prompt},
357
+ name=SemanticConvention.GEN_AI_CONTENT_PROMPT_EVENT,
358
+ attributes={SemanticConvention.GEN_AI_CONTENT_PROMPT: prompt},
359
359
  )
360
360
 
361
361
  output_tokens = 0
@@ -368,13 +368,13 @@ def process_chat_rag_response(response, request_model, pricing_info, server_port
368
368
  aggregated_completion.append(content)
369
369
  output_tokens += general_tokens(content)
370
370
  if kwargs.get('tools'):
371
- span.set_attribute(SemanticConvetion.GEN_AI_TOOL_CALLS,
371
+ span.set_attribute(SemanticConvention.GEN_AI_TOOL_CALLS,
372
372
  str(choices[i].get('message', {}).get('tool_calls')))
373
373
  # Set output type based on actual content type.
374
374
  if isinstance(content, str):
375
- span.set_attribute(SemanticConvetion.GEN_AI_OUTPUT_TYPE, 'text')
375
+ span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, 'text')
376
376
  elif content is not None:
377
- span.set_attribute(SemanticConvetion.GEN_AI_OUTPUT_TYPE, 'json')
377
+ span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, 'json')
378
378
 
379
379
  # Concatenate completion responses.
380
380
  llmresponse = ''.join(aggregated_completion)
@@ -382,16 +382,16 @@ def process_chat_rag_response(response, request_model, pricing_info, server_port
382
382
  tokens['total_tokens'] = input_tokens + output_tokens
383
383
 
384
384
  cost = get_chat_model_cost(request_model, pricing_info, input_tokens, output_tokens)
385
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_COST, cost)
386
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
387
- span.set_attribute(SemanticConvetion.GEN_AI_USAGE_TOTAL_TOKENS, input_tokens + output_tokens)
385
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
386
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
387
+ span.set_attribute(SemanticConvention.GEN_AI_USAGE_TOTAL_TOKENS, input_tokens + output_tokens)
388
388
 
389
389
  span.set_status(Status(StatusCode.OK))
390
390
  # Emit a single aggregated completion event.
391
391
  if capture_message_content:
392
392
  span.add_event(
393
- name=SemanticConvetion.GEN_AI_CONTENT_COMPLETION_EVENT,
394
- attributes={SemanticConvetion.GEN_AI_CONTENT_COMPLETION: llmresponse},
393
+ name=SemanticConvention.GEN_AI_CONTENT_COMPLETION_EVENT,
394
+ attributes={SemanticConvention.GEN_AI_CONTENT_COMPLETION: llmresponse},
395
395
  )
396
396
  # Emit the rest of the events (choice and role-based events) as before.
397
397
  n = kwargs.get('n', 1)
@@ -14,7 +14,7 @@ from openlit.instrumentation.anthropic.utils import (
14
14
  process_chat_response,
15
15
  process_streaming_chat_response,
16
16
  )
17
- from openlit.semcov import SemanticConvetion
17
+ from openlit.semcov import SemanticConvention
18
18
 
19
19
  # Initialize logger for logging potential issues and operations
20
20
  logger = logging.getLogger(__name__)
@@ -113,7 +113,7 @@ def messages(version, environment, application_name, tracer, event_provider,
113
113
  server_address, server_port = set_server_address_and_port(instance, 'api.anthropic.com', 443)
114
114
  request_model = kwargs.get('model', 'claude-3-5-sonnet-latest')
115
115
 
116
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
116
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
117
117
 
118
118
  # pylint: disable=no-else-return
119
119
  if streaming:
@@ -14,7 +14,7 @@ from openlit.instrumentation.anthropic.utils import (
14
14
  process_chat_response,
15
15
  process_streaming_chat_response,
16
16
  )
17
- from openlit.semcov import SemanticConvetion
17
+ from openlit.semcov import SemanticConvention
18
18
 
19
19
  # Initialize logger for logging potential issues and operations
20
20
  logger = logging.getLogger(__name__)
@@ -113,7 +113,7 @@ def async_messages(version, environment, application_name, tracer, event_provide
113
113
  server_address, server_port = set_server_address_and_port(instance, 'api.anthropic.com', 443)
114
114
  request_model = kwargs.get('model', 'claude-3-5-sonnet-latest')
115
115
 
116
- span_name = f'{SemanticConvetion.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
116
+ span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
117
117
 
118
118
  # pylint: disable=no-else-return
119
119
  if streaming: