mseep-agentops 0.4.18__py3-none-any.whl → 0.4.23__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 (153) hide show
  1. agentops/__init__.py +0 -0
  2. agentops/client/api/base.py +28 -30
  3. agentops/client/api/versions/v3.py +29 -25
  4. agentops/client/api/versions/v4.py +87 -46
  5. agentops/client/client.py +98 -29
  6. agentops/client/http/README.md +87 -0
  7. agentops/client/http/http_client.py +126 -172
  8. agentops/config.py +8 -2
  9. agentops/instrumentation/OpenTelemetry.md +133 -0
  10. agentops/instrumentation/README.md +167 -0
  11. agentops/instrumentation/__init__.py +13 -1
  12. agentops/instrumentation/agentic/ag2/__init__.py +18 -0
  13. agentops/instrumentation/agentic/ag2/instrumentor.py +922 -0
  14. agentops/instrumentation/agentic/agno/__init__.py +19 -0
  15. agentops/instrumentation/agentic/agno/attributes/__init__.py +20 -0
  16. agentops/instrumentation/agentic/agno/attributes/agent.py +250 -0
  17. agentops/instrumentation/agentic/agno/attributes/metrics.py +214 -0
  18. agentops/instrumentation/agentic/agno/attributes/storage.py +158 -0
  19. agentops/instrumentation/agentic/agno/attributes/team.py +195 -0
  20. agentops/instrumentation/agentic/agno/attributes/tool.py +210 -0
  21. agentops/instrumentation/agentic/agno/attributes/workflow.py +254 -0
  22. agentops/instrumentation/agentic/agno/instrumentor.py +1313 -0
  23. agentops/instrumentation/agentic/crewai/LICENSE +201 -0
  24. agentops/instrumentation/agentic/crewai/NOTICE.md +10 -0
  25. agentops/instrumentation/agentic/crewai/__init__.py +6 -0
  26. agentops/instrumentation/agentic/crewai/crewai_span_attributes.py +335 -0
  27. agentops/instrumentation/agentic/crewai/instrumentation.py +535 -0
  28. agentops/instrumentation/agentic/crewai/version.py +1 -0
  29. agentops/instrumentation/agentic/google_adk/__init__.py +19 -0
  30. agentops/instrumentation/agentic/google_adk/instrumentor.py +68 -0
  31. agentops/instrumentation/agentic/google_adk/patch.py +767 -0
  32. agentops/instrumentation/agentic/haystack/__init__.py +1 -0
  33. agentops/instrumentation/agentic/haystack/instrumentor.py +186 -0
  34. agentops/instrumentation/agentic/langgraph/__init__.py +3 -0
  35. agentops/instrumentation/agentic/langgraph/attributes.py +54 -0
  36. agentops/instrumentation/agentic/langgraph/instrumentation.py +598 -0
  37. agentops/instrumentation/agentic/langgraph/version.py +1 -0
  38. agentops/instrumentation/agentic/openai_agents/README.md +156 -0
  39. agentops/instrumentation/agentic/openai_agents/SPANS.md +145 -0
  40. agentops/instrumentation/agentic/openai_agents/TRACING_API.md +144 -0
  41. agentops/instrumentation/agentic/openai_agents/__init__.py +30 -0
  42. agentops/instrumentation/agentic/openai_agents/attributes/common.py +549 -0
  43. agentops/instrumentation/agentic/openai_agents/attributes/completion.py +172 -0
  44. agentops/instrumentation/agentic/openai_agents/attributes/model.py +58 -0
  45. agentops/instrumentation/agentic/openai_agents/attributes/tokens.py +275 -0
  46. agentops/instrumentation/agentic/openai_agents/exporter.py +469 -0
  47. agentops/instrumentation/agentic/openai_agents/instrumentor.py +107 -0
  48. agentops/instrumentation/agentic/openai_agents/processor.py +58 -0
  49. agentops/instrumentation/agentic/smolagents/README.md +88 -0
  50. agentops/instrumentation/agentic/smolagents/__init__.py +12 -0
  51. agentops/instrumentation/agentic/smolagents/attributes/agent.py +354 -0
  52. agentops/instrumentation/agentic/smolagents/attributes/model.py +205 -0
  53. agentops/instrumentation/agentic/smolagents/instrumentor.py +286 -0
  54. agentops/instrumentation/agentic/smolagents/stream_wrapper.py +258 -0
  55. agentops/instrumentation/agentic/xpander/__init__.py +15 -0
  56. agentops/instrumentation/agentic/xpander/context.py +112 -0
  57. agentops/instrumentation/agentic/xpander/instrumentor.py +877 -0
  58. agentops/instrumentation/agentic/xpander/trace_probe.py +86 -0
  59. agentops/instrumentation/agentic/xpander/version.py +3 -0
  60. agentops/instrumentation/common/README.md +65 -0
  61. agentops/instrumentation/common/attributes.py +1 -2
  62. agentops/instrumentation/providers/anthropic/__init__.py +24 -0
  63. agentops/instrumentation/providers/anthropic/attributes/__init__.py +23 -0
  64. agentops/instrumentation/providers/anthropic/attributes/common.py +64 -0
  65. agentops/instrumentation/providers/anthropic/attributes/message.py +541 -0
  66. agentops/instrumentation/providers/anthropic/attributes/tools.py +231 -0
  67. agentops/instrumentation/providers/anthropic/event_handler_wrapper.py +90 -0
  68. agentops/instrumentation/providers/anthropic/instrumentor.py +146 -0
  69. agentops/instrumentation/providers/anthropic/stream_wrapper.py +436 -0
  70. agentops/instrumentation/providers/google_genai/README.md +33 -0
  71. agentops/instrumentation/providers/google_genai/__init__.py +24 -0
  72. agentops/instrumentation/providers/google_genai/attributes/__init__.py +25 -0
  73. agentops/instrumentation/providers/google_genai/attributes/chat.py +125 -0
  74. agentops/instrumentation/providers/google_genai/attributes/common.py +88 -0
  75. agentops/instrumentation/providers/google_genai/attributes/model.py +284 -0
  76. agentops/instrumentation/providers/google_genai/instrumentor.py +170 -0
  77. agentops/instrumentation/providers/google_genai/stream_wrapper.py +238 -0
  78. agentops/instrumentation/providers/ibm_watsonx_ai/__init__.py +28 -0
  79. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/__init__.py +27 -0
  80. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/attributes.py +277 -0
  81. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/common.py +104 -0
  82. agentops/instrumentation/providers/ibm_watsonx_ai/instrumentor.py +162 -0
  83. agentops/instrumentation/providers/ibm_watsonx_ai/stream_wrapper.py +302 -0
  84. agentops/instrumentation/providers/mem0/__init__.py +45 -0
  85. agentops/instrumentation/providers/mem0/common.py +377 -0
  86. agentops/instrumentation/providers/mem0/instrumentor.py +270 -0
  87. agentops/instrumentation/providers/mem0/memory.py +430 -0
  88. agentops/instrumentation/providers/openai/__init__.py +21 -0
  89. agentops/instrumentation/providers/openai/attributes/__init__.py +7 -0
  90. agentops/instrumentation/providers/openai/attributes/common.py +55 -0
  91. agentops/instrumentation/providers/openai/attributes/response.py +607 -0
  92. agentops/instrumentation/providers/openai/config.py +36 -0
  93. agentops/instrumentation/providers/openai/instrumentor.py +312 -0
  94. agentops/instrumentation/providers/openai/stream_wrapper.py +941 -0
  95. agentops/instrumentation/providers/openai/utils.py +44 -0
  96. agentops/instrumentation/providers/openai/v0.py +176 -0
  97. agentops/instrumentation/providers/openai/v0_wrappers.py +483 -0
  98. agentops/instrumentation/providers/openai/wrappers/__init__.py +30 -0
  99. agentops/instrumentation/providers/openai/wrappers/assistant.py +277 -0
  100. agentops/instrumentation/providers/openai/wrappers/chat.py +259 -0
  101. agentops/instrumentation/providers/openai/wrappers/completion.py +109 -0
  102. agentops/instrumentation/providers/openai/wrappers/embeddings.py +94 -0
  103. agentops/instrumentation/providers/openai/wrappers/image_gen.py +75 -0
  104. agentops/instrumentation/providers/openai/wrappers/responses.py +191 -0
  105. agentops/instrumentation/providers/openai/wrappers/shared.py +81 -0
  106. agentops/instrumentation/utilities/concurrent_futures/__init__.py +10 -0
  107. agentops/instrumentation/utilities/concurrent_futures/instrumentation.py +206 -0
  108. agentops/integration/callbacks/dspy/__init__.py +11 -0
  109. agentops/integration/callbacks/dspy/callback.py +471 -0
  110. agentops/integration/callbacks/langchain/README.md +59 -0
  111. agentops/integration/callbacks/langchain/__init__.py +15 -0
  112. agentops/integration/callbacks/langchain/callback.py +791 -0
  113. agentops/integration/callbacks/langchain/utils.py +54 -0
  114. agentops/legacy/crewai.md +121 -0
  115. agentops/logging/instrument_logging.py +4 -0
  116. agentops/sdk/README.md +220 -0
  117. agentops/sdk/core.py +75 -32
  118. agentops/sdk/descriptors/classproperty.py +28 -0
  119. agentops/sdk/exporters.py +152 -33
  120. agentops/semconv/README.md +125 -0
  121. agentops/semconv/span_kinds.py +0 -2
  122. agentops/validation.py +102 -63
  123. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/METADATA +30 -40
  124. mseep_agentops-0.4.23.dist-info/RECORD +178 -0
  125. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/WHEEL +1 -2
  126. mseep_agentops-0.4.18.dist-info/RECORD +0 -94
  127. mseep_agentops-0.4.18.dist-info/top_level.txt +0 -2
  128. tests/conftest.py +0 -10
  129. tests/unit/client/__init__.py +0 -1
  130. tests/unit/client/test_http_adapter.py +0 -221
  131. tests/unit/client/test_http_client.py +0 -206
  132. tests/unit/conftest.py +0 -54
  133. tests/unit/sdk/__init__.py +0 -1
  134. tests/unit/sdk/instrumentation_tester.py +0 -207
  135. tests/unit/sdk/test_attributes.py +0 -392
  136. tests/unit/sdk/test_concurrent_instrumentation.py +0 -468
  137. tests/unit/sdk/test_decorators.py +0 -763
  138. tests/unit/sdk/test_exporters.py +0 -241
  139. tests/unit/sdk/test_factory.py +0 -1188
  140. tests/unit/sdk/test_internal_span_processor.py +0 -397
  141. tests/unit/sdk/test_resource_attributes.py +0 -35
  142. tests/unit/test_config.py +0 -82
  143. tests/unit/test_context_manager.py +0 -777
  144. tests/unit/test_events.py +0 -27
  145. tests/unit/test_host_env.py +0 -54
  146. tests/unit/test_init_py.py +0 -501
  147. tests/unit/test_serialization.py +0 -433
  148. tests/unit/test_session.py +0 -676
  149. tests/unit/test_user_agent.py +0 -34
  150. tests/unit/test_validation.py +0 -405
  151. {tests → agentops/instrumentation/agentic/openai_agents/attributes}/__init__.py +0 -0
  152. /tests/unit/__init__.py → /agentops/instrumentation/providers/openai/attributes/tools.py +0 -0
  153. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,312 @@
1
+ """OpenAI API Instrumentation for AgentOps
2
+
3
+ This module provides comprehensive instrumentation for the OpenAI API, including:
4
+ - Chat completions (streaming and non-streaming)
5
+ - Regular completions
6
+ - Embeddings
7
+ - Image generation
8
+ - Assistants API (create, runs, messages)
9
+ - Responses API (Agents SDK)
10
+
11
+ The instrumentation supports both sync and async methods, metrics collection,
12
+ and distributed tracing.
13
+ """
14
+
15
+ from typing import Dict, Any
16
+ from wrapt import wrap_function_wrapper
17
+
18
+ from opentelemetry.metrics import Meter
19
+
20
+ from agentops.logging import logger
21
+ from agentops.instrumentation.common import (
22
+ CommonInstrumentor,
23
+ InstrumentorConfig,
24
+ WrapConfig,
25
+ StandardMetrics,
26
+ MetricsRecorder,
27
+ )
28
+ from agentops.instrumentation.providers.openai import LIBRARY_NAME, LIBRARY_VERSION
29
+ from agentops.instrumentation.providers.openai.config import Config
30
+ from agentops.instrumentation.providers.openai.utils import is_openai_v1
31
+ from agentops.instrumentation.providers.openai.wrappers import (
32
+ handle_completion_attributes,
33
+ handle_embeddings_attributes,
34
+ handle_image_gen_attributes,
35
+ handle_assistant_attributes,
36
+ handle_run_attributes,
37
+ handle_run_retrieve_attributes,
38
+ handle_run_stream_attributes,
39
+ handle_messages_attributes,
40
+ )
41
+ from agentops.instrumentation.providers.openai.stream_wrapper import (
42
+ chat_completion_stream_wrapper,
43
+ async_chat_completion_stream_wrapper,
44
+ responses_stream_wrapper,
45
+ async_responses_stream_wrapper,
46
+ )
47
+ from agentops.instrumentation.providers.openai.v0 import OpenAIV0Instrumentor
48
+ from agentops.semconv import Meters
49
+
50
+ _instruments = ("openai >= 0.27.0",)
51
+
52
+
53
+ class OpenaiInstrumentor(CommonInstrumentor):
54
+ """An instrumentor for OpenAI's client library with comprehensive coverage."""
55
+
56
+ def __init__(
57
+ self,
58
+ enrich_assistant: bool = False,
59
+ enrich_token_usage: bool = False,
60
+ exception_logger=None,
61
+ get_common_metrics_attributes=None,
62
+ upload_base64_image=None,
63
+ enable_trace_context_propagation: bool = True,
64
+ ):
65
+ # Configure the global config with provided options
66
+ Config.enrich_assistant = enrich_assistant
67
+ Config.enrich_token_usage = enrich_token_usage
68
+ Config.exception_logger = exception_logger
69
+ Config.get_common_metrics_attributes = get_common_metrics_attributes or (lambda: {})
70
+ Config.upload_base64_image = upload_base64_image
71
+ Config.enable_trace_context_propagation = enable_trace_context_propagation
72
+
73
+ # Create instrumentor config
74
+ config = InstrumentorConfig(
75
+ library_name=LIBRARY_NAME,
76
+ library_version=LIBRARY_VERSION,
77
+ wrapped_methods=self._get_wrapped_methods(),
78
+ metrics_enabled=True,
79
+ dependencies=_instruments,
80
+ )
81
+
82
+ super().__init__(config)
83
+
84
+ def _initialize(self, **kwargs):
85
+ """Handle version-specific initialization."""
86
+ if not is_openai_v1():
87
+ # For v0, use the legacy instrumentor
88
+ OpenAIV0Instrumentor().instrument(**kwargs)
89
+ # Skip normal instrumentation
90
+ self.config.wrapped_methods = []
91
+
92
+ def _custom_wrap(self, **kwargs):
93
+ """Add custom wrappers for streaming functionality."""
94
+ if is_openai_v1() and self._tracer:
95
+ # from wrapt import wrap_function_wrapper
96
+ # # Add streaming wrappers for v1
97
+ try:
98
+ # Chat completion streaming wrappers
99
+
100
+ wrap_function_wrapper(
101
+ "openai.resources.chat.completions",
102
+ "Completions.create",
103
+ chat_completion_stream_wrapper(self._tracer),
104
+ )
105
+
106
+ wrap_function_wrapper(
107
+ "openai.resources.chat.completions",
108
+ "AsyncCompletions.create",
109
+ async_chat_completion_stream_wrapper(self._tracer),
110
+ )
111
+
112
+ # Beta chat completion streaming wrappers
113
+ wrap_function_wrapper(
114
+ "openai.resources.beta.chat.completions",
115
+ "Completions.parse",
116
+ chat_completion_stream_wrapper(self._tracer),
117
+ )
118
+
119
+ wrap_function_wrapper(
120
+ "openai.resources.beta.chat.completions",
121
+ "AsyncCompletions.parse",
122
+ async_chat_completion_stream_wrapper(self._tracer),
123
+ )
124
+
125
+ # Responses API streaming wrappers
126
+ wrap_function_wrapper(
127
+ "openai.resources.responses",
128
+ "Responses.create",
129
+ responses_stream_wrapper(self._tracer),
130
+ )
131
+
132
+ wrap_function_wrapper(
133
+ "openai.resources.responses",
134
+ "AsyncResponses.create",
135
+ async_responses_stream_wrapper(self._tracer),
136
+ )
137
+ except Exception as e:
138
+ logger.warning(f"[OPENAI INSTRUMENTOR] Error setting up OpenAI streaming wrappers: {e}")
139
+ else:
140
+ if not is_openai_v1():
141
+ logger.debug("[OPENAI INSTRUMENTOR] Skipping custom wrapping - not using OpenAI v1")
142
+ if not self._tracer:
143
+ logger.debug("[OPENAI INSTRUMENTOR] Skipping custom wrapping - no tracer available")
144
+
145
+ def _create_metrics(self, meter: Meter) -> Dict[str, Any]:
146
+ """Create metrics for OpenAI instrumentation."""
147
+ metrics = StandardMetrics.create_standard_metrics(meter)
148
+
149
+ # Add OpenAI-specific metrics
150
+ metrics.update(
151
+ {
152
+ "chat_choice_counter": meter.create_counter(
153
+ name=Meters.LLM_GENERATION_CHOICES,
154
+ unit="choice",
155
+ description="Number of choices returned by chat completions call",
156
+ ),
157
+ "streaming_time_to_first_token": meter.create_histogram(
158
+ name=Meters.LLM_STREAMING_TIME_TO_FIRST_TOKEN,
159
+ unit="s",
160
+ description="Time to first token in streaming chat completions",
161
+ ),
162
+ "streaming_time_to_generate": meter.create_histogram(
163
+ name=Meters.LLM_STREAMING_TIME_TO_GENERATE,
164
+ unit="s",
165
+ description="Time between first token and completion in streaming chat completions",
166
+ ),
167
+ "embeddings_vector_size_counter": meter.create_counter(
168
+ name=Meters.LLM_EMBEDDINGS_VECTOR_SIZE,
169
+ unit="element",
170
+ description="The size of returned vector",
171
+ ),
172
+ "embeddings_exception_counter": meter.create_counter(
173
+ name=Meters.LLM_EMBEDDINGS_EXCEPTIONS,
174
+ unit="time",
175
+ description="Number of exceptions occurred during embeddings operation",
176
+ ),
177
+ "image_gen_exception_counter": meter.create_counter(
178
+ name=Meters.LLM_IMAGE_GENERATIONS_EXCEPTIONS,
179
+ unit="time",
180
+ description="Number of exceptions occurred during image generations operation",
181
+ ),
182
+ }
183
+ )
184
+
185
+ return metrics
186
+
187
+ def _custom_unwrap(self, **kwargs):
188
+ """Handle version-specific uninstrumentation."""
189
+ if not is_openai_v1():
190
+ OpenAIV0Instrumentor().uninstrument(**kwargs)
191
+
192
+ def _get_wrapped_methods(self) -> list[WrapConfig]:
193
+ """Get all methods that should be wrapped.
194
+
195
+ Note: Chat completions and Responses API methods are NOT included here
196
+ as they are wrapped directly in _custom_wrap to support streaming.
197
+ """
198
+ wrapped_methods = []
199
+
200
+ # Regular completions
201
+ wrapped_methods.extend(
202
+ [
203
+ WrapConfig(
204
+ trace_name="openai.completion",
205
+ package="openai.resources.completions",
206
+ class_name="Completions",
207
+ method_name="create",
208
+ handler=handle_completion_attributes,
209
+ ),
210
+ WrapConfig(
211
+ trace_name="openai.completion",
212
+ package="openai.resources.completions",
213
+ class_name="AsyncCompletions",
214
+ method_name="create",
215
+ handler=handle_completion_attributes,
216
+ is_async=True,
217
+ ),
218
+ ]
219
+ )
220
+
221
+ # Embeddings
222
+ wrapped_methods.extend(
223
+ [
224
+ WrapConfig(
225
+ trace_name="openai.embeddings",
226
+ package="openai.resources.embeddings",
227
+ class_name="Embeddings",
228
+ method_name="create",
229
+ handler=handle_embeddings_attributes,
230
+ ),
231
+ WrapConfig(
232
+ trace_name="openai.embeddings",
233
+ package="openai.resources.embeddings",
234
+ class_name="AsyncEmbeddings",
235
+ method_name="create",
236
+ handler=handle_embeddings_attributes,
237
+ is_async=True,
238
+ ),
239
+ ]
240
+ )
241
+
242
+ # Image generation
243
+ wrapped_methods.append(
244
+ WrapConfig(
245
+ trace_name="openai.images.generate",
246
+ package="openai.resources.images",
247
+ class_name="Images",
248
+ method_name="generate",
249
+ handler=handle_image_gen_attributes,
250
+ )
251
+ )
252
+
253
+ # Beta APIs - these may not be available in all versions
254
+ beta_methods = []
255
+
256
+ # Assistants
257
+ beta_methods.append(
258
+ WrapConfig(
259
+ trace_name="openai.assistants.create",
260
+ package="openai.resources.beta.assistants",
261
+ class_name="Assistants",
262
+ method_name="create",
263
+ handler=handle_assistant_attributes,
264
+ )
265
+ )
266
+
267
+ # Runs
268
+ beta_methods.extend(
269
+ [
270
+ WrapConfig(
271
+ trace_name="openai.runs.create",
272
+ package="openai.resources.beta.threads.runs",
273
+ class_name="Runs",
274
+ method_name="create",
275
+ handler=handle_run_attributes,
276
+ ),
277
+ WrapConfig(
278
+ trace_name="openai.runs.retrieve",
279
+ package="openai.resources.beta.threads.runs",
280
+ class_name="Runs",
281
+ method_name="retrieve",
282
+ handler=handle_run_retrieve_attributes,
283
+ ),
284
+ WrapConfig(
285
+ trace_name="openai.runs.create_and_stream",
286
+ package="openai.resources.beta.threads.runs",
287
+ class_name="Runs",
288
+ method_name="create_and_stream",
289
+ handler=handle_run_stream_attributes,
290
+ ),
291
+ ]
292
+ )
293
+
294
+ # Messages
295
+ beta_methods.append(
296
+ WrapConfig(
297
+ trace_name="openai.messages.list",
298
+ package="openai.resources.beta.threads.messages",
299
+ class_name="Messages",
300
+ method_name="list",
301
+ handler=handle_messages_attributes,
302
+ )
303
+ )
304
+
305
+ # Add beta methods to wrapped methods (they might fail)
306
+ wrapped_methods.extend(beta_methods)
307
+
308
+ return wrapped_methods
309
+
310
+ def get_metrics_recorder(self) -> MetricsRecorder:
311
+ """Get a metrics recorder for use in wrappers."""
312
+ return MetricsRecorder(self._metrics)