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,7 +5,11 @@ Module for monitoring Dynamiq calls.
5
5
 
6
6
  import logging
7
7
  from opentelemetry.trace import SpanKind, Status, StatusCode
8
- from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
8
+ from opentelemetry.sdk.resources import (
9
+ SERVICE_NAME,
10
+ TELEMETRY_SDK_NAME,
11
+ DEPLOYMENT_ENVIRONMENT,
12
+ )
9
13
  from openlit.__helpers import (
10
14
  handle_exception,
11
15
  )
@@ -14,8 +18,18 @@ from openlit.semcov import SemanticConvention
14
18
  # Initialize logger for logging potential issues and operations
15
19
  logger = logging.getLogger(__name__)
16
20
 
17
- def dynamiq_wrap(gen_ai_endpoint, version, environment, application_name,
18
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
21
+
22
+ def dynamiq_wrap(
23
+ gen_ai_endpoint,
24
+ version,
25
+ environment,
26
+ application_name,
27
+ tracer,
28
+ pricing_info,
29
+ capture_message_content,
30
+ metrics,
31
+ disable_metrics,
32
+ ):
19
33
  """
20
34
  Generates a telemetry wrapper for chat completions to collect metrics.
21
35
 
@@ -50,49 +64,76 @@ def dynamiq_wrap(gen_ai_endpoint, version, environment, application_name,
50
64
  """
51
65
 
52
66
  # pylint: disable=line-too-long
53
- with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
67
+ with tracer.start_as_current_span(
68
+ gen_ai_endpoint, kind=SpanKind.CLIENT
69
+ ) as span:
54
70
  response = wrapped(*args, **kwargs)
55
71
 
56
72
  try:
57
73
  # Set base span attribues
58
74
  span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
59
- span.set_attribute(SemanticConvention.GEN_AI_SYSTEM,
60
- SemanticConvention.GEN_AI_SYSTEM_DYNAMIQ)
61
- span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
62
- SemanticConvention.GEN_AI_OPERATION_TYPE_AGENT)
63
- span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT,
64
- gen_ai_endpoint)
65
- span.set_attribute(SERVICE_NAME,
66
- application_name)
67
- span.set_attribute(DEPLOYMENT_ENVIRONMENT,
68
- environment)
75
+ span.set_attribute(
76
+ SemanticConvention.GEN_AI_SYSTEM,
77
+ SemanticConvention.GEN_AI_SYSTEM_DYNAMIQ,
78
+ )
79
+ span.set_attribute(
80
+ SemanticConvention.GEN_AI_OPERATION,
81
+ SemanticConvention.GEN_AI_OPERATION_TYPE_AGENT,
82
+ )
83
+ span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT, gen_ai_endpoint)
84
+ span.set_attribute(SERVICE_NAME, application_name)
85
+ span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
69
86
 
70
87
  if gen_ai_endpoint == "dynamiq.agent_run":
71
- span.set_attribute(SemanticConvention.GEN_AI_AGENT_ID,
72
- getattr(instance, 'id', '') or '')
73
- span.set_attribute(SemanticConvention.GEN_AI_AGENT_ROLE,
74
- getattr(instance, 'name', '') or '')
75
- span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL,
76
- getattr(getattr(instance, 'llm', None), 'model', '') or '')
77
- span.set_attribute(SemanticConvention.GEN_AI_AGENT_TYPE,
78
- str(getattr(instance, 'type', '')) or '')
88
+ span.set_attribute(
89
+ SemanticConvention.GEN_AI_AGENT_ID,
90
+ getattr(instance, "id", "") or "",
91
+ )
92
+ span.set_attribute(
93
+ SemanticConvention.GEN_AI_AGENT_ROLE,
94
+ getattr(instance, "name", "") or "",
95
+ )
96
+ span.set_attribute(
97
+ SemanticConvention.GEN_AI_REQUEST_MODEL,
98
+ getattr(getattr(instance, "llm", None), "model", "") or "",
99
+ )
100
+ span.set_attribute(
101
+ SemanticConvention.GEN_AI_AGENT_TYPE,
102
+ str(getattr(instance, "type", "")) or "",
103
+ )
79
104
 
80
105
  elif gen_ai_endpoint == "dynamiq.workflow_run":
81
- span.set_attribute(SemanticConvention.GEN_AI_AGENT_ID,
82
- getattr(instance, 'id', '') or '')
83
- span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL,
84
- getattr(getattr(instance.flow, 'nodes', [None])[0], 'model', 'default_model'))
106
+ span.set_attribute(
107
+ SemanticConvention.GEN_AI_AGENT_ID,
108
+ getattr(instance, "id", "") or "",
109
+ )
110
+ span.set_attribute(
111
+ SemanticConvention.GEN_AI_REQUEST_MODEL,
112
+ getattr(
113
+ getattr(instance.flow, "nodes", [None])[0],
114
+ "model",
115
+ "default_model",
116
+ ),
117
+ )
85
118
 
86
119
  elif gen_ai_endpoint == "dynamiq.memory_add":
87
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
88
- SemanticConvention.DB_OPERATION_ADD)
89
- span.set_attribute(SemanticConvention.DB_METADATA, str(kwargs.get('metadata', '')))
120
+ span.set_attribute(
121
+ SemanticConvention.DB_OPERATION_NAME,
122
+ SemanticConvention.DB_OPERATION_ADD,
123
+ )
124
+ span.set_attribute(
125
+ SemanticConvention.DB_METADATA, str(kwargs.get("metadata", ""))
126
+ )
90
127
 
91
128
  elif gen_ai_endpoint == "dynamiq.memory_search":
92
- query_value = kwargs.get('query', '') or (args[0] if args else '')
93
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
94
- SemanticConvention.DB_OPERATION_GET)
95
- span.set_attribute(SemanticConvention.DB_FILTER, str(kwargs.get('filters', '')))
129
+ query_value = kwargs.get("query", "") or (args[0] if args else "")
130
+ span.set_attribute(
131
+ SemanticConvention.DB_OPERATION_NAME,
132
+ SemanticConvention.DB_OPERATION_GET,
133
+ )
134
+ span.set_attribute(
135
+ SemanticConvention.DB_FILTER, str(kwargs.get("filters", ""))
136
+ )
96
137
  span.set_attribute(SemanticConvention.DB_STATEMENT, query_value)
97
138
 
98
139
  span.set_status(Status(StatusCode.OK))
@@ -10,6 +10,7 @@ from openlit.instrumentation.elevenlabs.async_elevenlabs import async_generate
10
10
 
11
11
  _instruments = ("elevenlabs >= 1.4.0",)
12
12
 
13
+
13
14
  class ElevenLabsInstrumentor(BaseInstrumentor):
14
15
  """
15
16
  An instrumentor for ElevenLabs client library.
@@ -32,16 +33,34 @@ class ElevenLabsInstrumentor(BaseInstrumentor):
32
33
  wrap_function_wrapper(
33
34
  "elevenlabs.text_to_speech.client",
34
35
  "TextToSpeechClient.convert",
35
- generate("elevenlabs.text_to_speech", version, environment, application_name,
36
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
36
+ generate(
37
+ "elevenlabs.text_to_speech",
38
+ version,
39
+ environment,
40
+ application_name,
41
+ tracer,
42
+ pricing_info,
43
+ capture_message_content,
44
+ metrics,
45
+ disable_metrics,
46
+ ),
37
47
  )
38
48
 
39
49
  # async text_to_speech.convert
40
50
  wrap_function_wrapper(
41
51
  "elevenlabs.text_to_speech.client",
42
52
  "AsyncTextToSpeechClient.convert",
43
- async_generate("elevenlabs.text_to_speech", version, environment, application_name,
44
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
53
+ async_generate(
54
+ "elevenlabs.text_to_speech",
55
+ version,
56
+ environment,
57
+ application_name,
58
+ tracer,
59
+ pricing_info,
60
+ capture_message_content,
61
+ metrics,
62
+ disable_metrics,
63
+ ),
45
64
  )
46
65
 
47
66
  def _uninstrument(self, **kwargs):
@@ -8,8 +8,18 @@ from openlit.__helpers import handle_exception
8
8
  from openlit.instrumentation.elevenlabs.utils import process_audio_response
9
9
  from openlit.semcov import SemanticConvention
10
10
 
11
- def async_generate(gen_ai_endpoint, version, environment, application_name,
12
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
11
+
12
+ def async_generate(
13
+ gen_ai_endpoint,
14
+ version,
15
+ environment,
16
+ application_name,
17
+ tracer,
18
+ pricing_info,
19
+ capture_message_content,
20
+ metrics,
21
+ disable_metrics,
22
+ ):
13
23
  """
14
24
  Generates a telemetry wrapper for GenAI function call
15
25
  """
@@ -20,7 +30,9 @@ def async_generate(gen_ai_endpoint, version, environment, application_name,
20
30
  """
21
31
 
22
32
  server_address, server_port = "api.elevenlabs.io", 443
23
- request_model = kwargs.get("model", kwargs.get("model_id", "eleven_multilingual_v2"))
33
+ request_model = kwargs.get(
34
+ "model", kwargs.get("model_id", "eleven_multilingual_v2")
35
+ )
24
36
 
25
37
  span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO} {request_model}"
26
38
 
@@ -44,7 +56,7 @@ def async_generate(gen_ai_endpoint, version, environment, application_name,
44
56
  kwargs=kwargs,
45
57
  capture_message_content=capture_message_content,
46
58
  disable_metrics=disable_metrics,
47
- version=version
59
+ version=version,
48
60
  )
49
61
 
50
62
  except Exception as e:
@@ -8,8 +8,18 @@ from openlit.__helpers import handle_exception
8
8
  from openlit.instrumentation.elevenlabs.utils import process_audio_response
9
9
  from openlit.semcov import SemanticConvention
10
10
 
11
- def generate(gen_ai_endpoint, version, environment, application_name,
12
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
11
+
12
+ def generate(
13
+ gen_ai_endpoint,
14
+ version,
15
+ environment,
16
+ application_name,
17
+ tracer,
18
+ pricing_info,
19
+ capture_message_content,
20
+ metrics,
21
+ disable_metrics,
22
+ ):
13
23
  """
14
24
  Generates a telemetry wrapper for GenAI function call
15
25
  """
@@ -20,7 +30,9 @@ def generate(gen_ai_endpoint, version, environment, application_name,
20
30
  """
21
31
 
22
32
  server_address, server_port = "api.elevenlabs.io", 443
23
- request_model = kwargs.get("model", kwargs.get("model_id", "eleven_multilingual_v2"))
33
+ request_model = kwargs.get(
34
+ "model", kwargs.get("model_id", "eleven_multilingual_v2")
35
+ )
24
36
 
25
37
  span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO} {request_model}"
26
38
 
@@ -44,7 +56,7 @@ def generate(gen_ai_endpoint, version, environment, application_name,
44
56
  kwargs=kwargs,
45
57
  capture_message_content=capture_message_content,
46
58
  disable_metrics=disable_metrics,
47
- version=version
59
+ version=version,
48
60
  )
49
61
 
50
62
  except Exception as e:
@@ -1,9 +1,14 @@
1
1
  """
2
2
  ElevenLabs 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 (
@@ -12,14 +17,29 @@ from openlit.__helpers import (
12
17
  )
13
18
  from openlit.semcov import SemanticConvention
14
19
 
20
+
15
21
  def format_content(text):
16
22
  """
17
23
  Process text input to extract content.
18
24
  """
19
25
  return str(text) if text else ""
20
26
 
21
- def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_address, server_port,
22
- request_model, response_model, environment, application_name, is_stream, tbt, ttft, version):
27
+
28
+ def common_span_attributes(
29
+ scope,
30
+ gen_ai_operation,
31
+ gen_ai_system,
32
+ server_address,
33
+ server_port,
34
+ request_model,
35
+ response_model,
36
+ environment,
37
+ application_name,
38
+ is_stream,
39
+ tbt,
40
+ ttft,
41
+ version,
42
+ ):
23
43
  """
24
44
  Set common span attributes for both chat and RAG operations.
25
45
  """
@@ -30,7 +50,9 @@ def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_addres
30
50
  scope._span.set_attribute(SemanticConvention.SERVER_ADDRESS, server_address)
31
51
  scope._span.set_attribute(SemanticConvention.SERVER_PORT, server_port)
32
52
  scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL, request_model)
33
- scope._span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_MODEL, scope._response_model)
53
+ scope._span.set_attribute(
54
+ SemanticConvention.GEN_AI_RESPONSE_MODEL, scope._response_model
55
+ )
34
56
  scope._span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
35
57
  scope._span.set_attribute(SERVICE_NAME, application_name)
36
58
  scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IS_STREAM, is_stream)
@@ -38,8 +60,21 @@ def common_span_attributes(scope, gen_ai_operation, gen_ai_system, server_addres
38
60
  scope._span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT, scope._ttft)
39
61
  scope._span.set_attribute(SemanticConvention.GEN_AI_SDK_VERSION, version)
40
62
 
41
- def record_audio_metrics(metrics, gen_ai_operation, gen_ai_system, server_address, server_port,
42
- request_model, response_model, environment, application_name, start_time, end_time, cost):
63
+
64
+ def record_audio_metrics(
65
+ metrics,
66
+ gen_ai_operation,
67
+ gen_ai_system,
68
+ server_address,
69
+ server_port,
70
+ request_model,
71
+ response_model,
72
+ environment,
73
+ application_name,
74
+ start_time,
75
+ end_time,
76
+ cost,
77
+ ):
43
78
  """
44
79
  Record audio generation metrics for the operation.
45
80
  """
@@ -58,33 +93,64 @@ def record_audio_metrics(metrics, gen_ai_operation, gen_ai_system, server_addres
58
93
  metrics["genai_requests"].add(1, attributes)
59
94
  metrics["genai_cost"].record(cost, attributes)
60
95
 
61
- def common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, application_name,
62
- metrics, capture_message_content, disable_metrics, version):
96
+
97
+ def common_audio_logic(
98
+ scope,
99
+ gen_ai_endpoint,
100
+ pricing_info,
101
+ environment,
102
+ application_name,
103
+ metrics,
104
+ capture_message_content,
105
+ disable_metrics,
106
+ version,
107
+ ):
63
108
  """
64
109
  Process audio generation request and generate Telemetry
65
110
  """
66
111
 
67
112
  text = format_content(scope._kwargs.get("text", ""))
68
- request_model = scope._kwargs.get("model", scope._kwargs.get("model_id", "eleven_multilingual_v2"))
113
+ request_model = scope._kwargs.get(
114
+ "model", scope._kwargs.get("model_id", "eleven_multilingual_v2")
115
+ )
69
116
  is_stream = False # ElevenLabs audio generation is not streaming
70
117
 
71
118
  cost = get_audio_model_cost(request_model, pricing_info, text)
72
119
 
73
120
  # Common Span Attributes
74
- common_span_attributes(scope,
75
- SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO, SemanticConvention.GEN_AI_SYSTEM_ELEVENLABS,
76
- scope._server_address, scope._server_port, request_model, request_model,
77
- environment, application_name, is_stream, scope._tbt, scope._ttft, version)
121
+ common_span_attributes(
122
+ scope,
123
+ SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO,
124
+ SemanticConvention.GEN_AI_SYSTEM_ELEVENLABS,
125
+ scope._server_address,
126
+ scope._server_port,
127
+ request_model,
128
+ request_model,
129
+ environment,
130
+ application_name,
131
+ is_stream,
132
+ scope._tbt,
133
+ scope._ttft,
134
+ version,
135
+ )
78
136
 
79
137
  # Span Attributes for Cost and Tokens
80
138
  scope._span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST, cost)
81
139
 
82
140
  # Span Attributes for Response parameters
83
- scope._span.set_attribute(SemanticConvention.GEN_AI_OUTPUT_TYPE, scope._kwargs.get("output_format", "mp3_44100_128"))
141
+ scope._span.set_attribute(
142
+ SemanticConvention.GEN_AI_OUTPUT_TYPE,
143
+ scope._kwargs.get("output_format", "mp3_44100_128"),
144
+ )
84
145
 
85
146
  # Audio-specific span attributes
86
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_AUDIO_VOICE, scope._kwargs.get("voice_id", ""))
87
- scope._span.set_attribute(SemanticConvention.GEN_AI_REQUEST_AUDIO_SETTINGS, str(scope._kwargs.get("voice_settings", "")))
147
+ scope._span.set_attribute(
148
+ SemanticConvention.GEN_AI_REQUEST_AUDIO_VOICE, scope._kwargs.get("voice_id", "")
149
+ )
150
+ scope._span.set_attribute(
151
+ SemanticConvention.GEN_AI_REQUEST_AUDIO_SETTINGS,
152
+ str(scope._kwargs.get("voice_settings", "")),
153
+ )
88
154
 
89
155
  # Span Attributes for Content
90
156
  if capture_message_content:
@@ -102,13 +168,39 @@ def common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, applic
102
168
 
103
169
  # Metrics
104
170
  if not disable_metrics:
105
- record_audio_metrics(metrics, SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO, SemanticConvention.GEN_AI_SYSTEM_ELEVENLABS,
106
- scope._server_address, scope._server_port, request_model, request_model, environment,
107
- application_name, scope._start_time, scope._end_time, cost)
171
+ record_audio_metrics(
172
+ metrics,
173
+ SemanticConvention.GEN_AI_OPERATION_TYPE_AUDIO,
174
+ SemanticConvention.GEN_AI_SYSTEM_ELEVENLABS,
175
+ scope._server_address,
176
+ scope._server_port,
177
+ request_model,
178
+ request_model,
179
+ environment,
180
+ application_name,
181
+ scope._start_time,
182
+ scope._end_time,
183
+ cost,
184
+ )
185
+
108
186
 
109
- def process_audio_response(response, gen_ai_endpoint, pricing_info, server_port, server_address,
110
- environment, application_name, metrics, start_time, span, args, kwargs, capture_message_content=False,
111
- disable_metrics=False, version="1.0.0"):
187
+ def process_audio_response(
188
+ response,
189
+ gen_ai_endpoint,
190
+ pricing_info,
191
+ server_port,
192
+ server_address,
193
+ environment,
194
+ application_name,
195
+ metrics,
196
+ start_time,
197
+ span,
198
+ args,
199
+ kwargs,
200
+ capture_message_content=False,
201
+ disable_metrics=False,
202
+ version="1.0.0",
203
+ ):
112
204
  """
113
205
  Process audio generation request and generate Telemetry
114
206
  """
@@ -123,11 +215,22 @@ def process_audio_response(response, gen_ai_endpoint, pricing_info, server_port,
123
215
  scope._args = args
124
216
 
125
217
  # Initialize streaming and timing values for ElevenLabs audio generation
126
- scope._response_model = kwargs.get("model", kwargs.get("model_id", "eleven_multilingual_v2"))
218
+ scope._response_model = kwargs.get(
219
+ "model", kwargs.get("model_id", "eleven_multilingual_v2")
220
+ )
127
221
  scope._tbt = 0.0
128
222
  scope._ttft = scope._end_time - scope._start_time
129
223
 
130
- common_audio_logic(scope, gen_ai_endpoint, pricing_info, environment, application_name,
131
- metrics, capture_message_content, disable_metrics, version)
224
+ common_audio_logic(
225
+ scope,
226
+ gen_ai_endpoint,
227
+ pricing_info,
228
+ environment,
229
+ application_name,
230
+ metrics,
231
+ capture_message_content,
232
+ disable_metrics,
233
+ version,
234
+ )
132
235
 
133
236
  return response
@@ -1,5 +1,6 @@
1
1
  # pylint: disable=useless-return, bad-staticmethod-argument, disable=duplicate-code
2
2
  """Initializer of Auto Instrumentation of EmbedChain Functions"""
3
+
3
4
  from typing import Collection
4
5
  import importlib.metadata
5
6
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
@@ -24,6 +25,7 @@ WRAPPED_METHODS = [
24
25
  },
25
26
  ]
26
27
 
28
+
27
29
  class EmbedChainInstrumentor(BaseInstrumentor):
28
30
  """An instrumentor for EmbedChain's client library."""
29
31
 
@@ -46,8 +48,15 @@ class EmbedChainInstrumentor(BaseInstrumentor):
46
48
  wrap_function_wrapper(
47
49
  wrap_package,
48
50
  wrap_object,
49
- wrapper(gen_ai_endpoint, version, environment, application_name,
50
- tracer, pricing_info, capture_message_content),
51
+ wrapper(
52
+ gen_ai_endpoint,
53
+ version,
54
+ environment,
55
+ application_name,
56
+ tracer,
57
+ pricing_info,
58
+ capture_message_content,
59
+ ),
51
60
  )
52
61
 
53
62
  @staticmethod
@@ -5,15 +5,27 @@ Module for monitoring EmbedChain applications.
5
5
 
6
6
  import logging
7
7
  from opentelemetry.trace import SpanKind, Status, StatusCode
8
- from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
8
+ from opentelemetry.sdk.resources import (
9
+ SERVICE_NAME,
10
+ TELEMETRY_SDK_NAME,
11
+ DEPLOYMENT_ENVIRONMENT,
12
+ )
9
13
  from openlit.__helpers import handle_exception
10
14
  from openlit.semcov import SemanticConvention
11
15
 
12
16
  # Initialize logger for logging potential issues and operations
13
17
  logger = logging.getLogger(__name__)
14
18
 
15
- def evaluate(gen_ai_endpoint, version, environment, application_name,
16
- tracer, pricing_info, capture_message_content):
19
+
20
+ def evaluate(
21
+ gen_ai_endpoint,
22
+ version,
23
+ environment,
24
+ application_name,
25
+ tracer,
26
+ pricing_info,
27
+ capture_message_content,
28
+ ):
17
29
  """
18
30
  Creates a wrapper around a function call to trace and log its execution metrics.
19
31
 
@@ -54,27 +66,36 @@ def evaluate(gen_ai_endpoint, version, environment, application_name,
54
66
  on the span based on the function's execution and response, and ensures
55
67
  errors are handled and logged appropriately.
56
68
  """
57
- with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
69
+ with tracer.start_as_current_span(
70
+ gen_ai_endpoint, kind=SpanKind.CLIENT
71
+ ) as span:
58
72
  response = wrapped(*args, **kwargs)
59
73
 
60
74
  try:
61
75
  span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
62
- span.set_attribute(SemanticConvention.GEN_AI_SYSTEM,
63
- SemanticConvention.GEN_AI_SYSTEM_EMBEDCHAIN)
64
- span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT,
65
- gen_ai_endpoint)
66
- span.set_attribute(DEPLOYMENT_ENVIRONMENT,
67
- environment)
68
- span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
69
- SemanticConvention.GEN_AI_OPERATION_TYPE_FRAMEWORK)
70
- span.set_attribute(SERVICE_NAME,
71
- application_name)
72
- span.set_attribute(SemanticConvention.GEN_AI_EVAL_CONTEXT_RELEVANCY,
73
- response["context_relevancy"])
74
- span.set_attribute(SemanticConvention.GEN_AI_EVAL_ANSWER_RELEVANCY,
75
- response["answer_relevancy"])
76
- span.set_attribute(SemanticConvention.GEN_AI_EVAL_GROUNDEDNESS,
77
- response["groundedness"])
76
+ span.set_attribute(
77
+ SemanticConvention.GEN_AI_SYSTEM,
78
+ SemanticConvention.GEN_AI_SYSTEM_EMBEDCHAIN,
79
+ )
80
+ span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT, gen_ai_endpoint)
81
+ span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
82
+ span.set_attribute(
83
+ SemanticConvention.GEN_AI_OPERATION,
84
+ SemanticConvention.GEN_AI_OPERATION_TYPE_FRAMEWORK,
85
+ )
86
+ span.set_attribute(SERVICE_NAME, application_name)
87
+ span.set_attribute(
88
+ SemanticConvention.GEN_AI_EVAL_CONTEXT_RELEVANCY,
89
+ response["context_relevancy"],
90
+ )
91
+ span.set_attribute(
92
+ SemanticConvention.GEN_AI_EVAL_ANSWER_RELEVANCY,
93
+ response["answer_relevancy"],
94
+ )
95
+ span.set_attribute(
96
+ SemanticConvention.GEN_AI_EVAL_GROUNDEDNESS,
97
+ response["groundedness"],
98
+ )
78
99
 
79
100
  span.set_status(Status(StatusCode.OK))
80
101
 
@@ -90,8 +111,16 @@ def evaluate(gen_ai_endpoint, version, environment, application_name,
90
111
 
91
112
  return wrapper
92
113
 
93
- def get_data_sources(gen_ai_endpoint, version, environment, application_name,
94
- tracer, pricing_info, capture_message_content):
114
+
115
+ def get_data_sources(
116
+ gen_ai_endpoint,
117
+ version,
118
+ environment,
119
+ application_name,
120
+ tracer,
121
+ pricing_info,
122
+ capture_message_content,
123
+ ):
95
124
  """
96
125
  Creates a wrapper around a function call to trace and log its execution metrics.
97
126
 
@@ -132,23 +161,27 @@ def get_data_sources(gen_ai_endpoint, version, environment, application_name,
132
161
  on the span based on the function's execution and response, and ensures
133
162
  errors are handled and logged appropriately.
134
163
  """
135
- with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
164
+ with tracer.start_as_current_span(
165
+ gen_ai_endpoint, kind=SpanKind.CLIENT
166
+ ) as span:
136
167
  response = wrapped(*args, **kwargs)
137
168
 
138
169
  try:
139
170
  span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
140
- span.set_attribute(SemanticConvention.GEN_AI_SYSTEM,
141
- SemanticConvention.GEN_AI_SYSTEM_EMBEDCHAIN)
142
- span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT,
143
- gen_ai_endpoint)
144
- span.set_attribute(DEPLOYMENT_ENVIRONMENT,
145
- environment)
146
- span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
147
- SemanticConvention.GEN_AI_OPERATION_TYPE_FRAMEWORK)
148
- span.set_attribute(SERVICE_NAME,
149
- application_name)
150
- span.set_attribute(SemanticConvention.GEN_AI_DATA_SOURCES,
151
- len(response))
171
+ span.set_attribute(
172
+ SemanticConvention.GEN_AI_SYSTEM,
173
+ SemanticConvention.GEN_AI_SYSTEM_EMBEDCHAIN,
174
+ )
175
+ span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT, gen_ai_endpoint)
176
+ span.set_attribute(DEPLOYMENT_ENVIRONMENT, environment)
177
+ span.set_attribute(
178
+ SemanticConvention.GEN_AI_OPERATION,
179
+ SemanticConvention.GEN_AI_OPERATION_TYPE_FRAMEWORK,
180
+ )
181
+ span.set_attribute(SERVICE_NAME, application_name)
182
+ span.set_attribute(
183
+ SemanticConvention.GEN_AI_DATA_SOURCES, len(response)
184
+ )
152
185
 
153
186
  span.set_status(Status(StatusCode.OK))
154
187