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.
- agentops/__init__.py +0 -0
- agentops/client/api/base.py +28 -30
- agentops/client/api/versions/v3.py +29 -25
- agentops/client/api/versions/v4.py +87 -46
- agentops/client/client.py +98 -29
- agentops/client/http/README.md +87 -0
- agentops/client/http/http_client.py +126 -172
- agentops/config.py +8 -2
- agentops/instrumentation/OpenTelemetry.md +133 -0
- agentops/instrumentation/README.md +167 -0
- agentops/instrumentation/__init__.py +13 -1
- agentops/instrumentation/agentic/ag2/__init__.py +18 -0
- agentops/instrumentation/agentic/ag2/instrumentor.py +922 -0
- agentops/instrumentation/agentic/agno/__init__.py +19 -0
- agentops/instrumentation/agentic/agno/attributes/__init__.py +20 -0
- agentops/instrumentation/agentic/agno/attributes/agent.py +250 -0
- agentops/instrumentation/agentic/agno/attributes/metrics.py +214 -0
- agentops/instrumentation/agentic/agno/attributes/storage.py +158 -0
- agentops/instrumentation/agentic/agno/attributes/team.py +195 -0
- agentops/instrumentation/agentic/agno/attributes/tool.py +210 -0
- agentops/instrumentation/agentic/agno/attributes/workflow.py +254 -0
- agentops/instrumentation/agentic/agno/instrumentor.py +1313 -0
- agentops/instrumentation/agentic/crewai/LICENSE +201 -0
- agentops/instrumentation/agentic/crewai/NOTICE.md +10 -0
- agentops/instrumentation/agentic/crewai/__init__.py +6 -0
- agentops/instrumentation/agentic/crewai/crewai_span_attributes.py +335 -0
- agentops/instrumentation/agentic/crewai/instrumentation.py +535 -0
- agentops/instrumentation/agentic/crewai/version.py +1 -0
- agentops/instrumentation/agentic/google_adk/__init__.py +19 -0
- agentops/instrumentation/agentic/google_adk/instrumentor.py +68 -0
- agentops/instrumentation/agentic/google_adk/patch.py +767 -0
- agentops/instrumentation/agentic/haystack/__init__.py +1 -0
- agentops/instrumentation/agentic/haystack/instrumentor.py +186 -0
- agentops/instrumentation/agentic/langgraph/__init__.py +3 -0
- agentops/instrumentation/agentic/langgraph/attributes.py +54 -0
- agentops/instrumentation/agentic/langgraph/instrumentation.py +598 -0
- agentops/instrumentation/agentic/langgraph/version.py +1 -0
- agentops/instrumentation/agentic/openai_agents/README.md +156 -0
- agentops/instrumentation/agentic/openai_agents/SPANS.md +145 -0
- agentops/instrumentation/agentic/openai_agents/TRACING_API.md +144 -0
- agentops/instrumentation/agentic/openai_agents/__init__.py +30 -0
- agentops/instrumentation/agentic/openai_agents/attributes/common.py +549 -0
- agentops/instrumentation/agentic/openai_agents/attributes/completion.py +172 -0
- agentops/instrumentation/agentic/openai_agents/attributes/model.py +58 -0
- agentops/instrumentation/agentic/openai_agents/attributes/tokens.py +275 -0
- agentops/instrumentation/agentic/openai_agents/exporter.py +469 -0
- agentops/instrumentation/agentic/openai_agents/instrumentor.py +107 -0
- agentops/instrumentation/agentic/openai_agents/processor.py +58 -0
- agentops/instrumentation/agentic/smolagents/README.md +88 -0
- agentops/instrumentation/agentic/smolagents/__init__.py +12 -0
- agentops/instrumentation/agentic/smolagents/attributes/agent.py +354 -0
- agentops/instrumentation/agentic/smolagents/attributes/model.py +205 -0
- agentops/instrumentation/agentic/smolagents/instrumentor.py +286 -0
- agentops/instrumentation/agentic/smolagents/stream_wrapper.py +258 -0
- agentops/instrumentation/agentic/xpander/__init__.py +15 -0
- agentops/instrumentation/agentic/xpander/context.py +112 -0
- agentops/instrumentation/agentic/xpander/instrumentor.py +877 -0
- agentops/instrumentation/agentic/xpander/trace_probe.py +86 -0
- agentops/instrumentation/agentic/xpander/version.py +3 -0
- agentops/instrumentation/common/README.md +65 -0
- agentops/instrumentation/common/attributes.py +1 -2
- agentops/instrumentation/providers/anthropic/__init__.py +24 -0
- agentops/instrumentation/providers/anthropic/attributes/__init__.py +23 -0
- agentops/instrumentation/providers/anthropic/attributes/common.py +64 -0
- agentops/instrumentation/providers/anthropic/attributes/message.py +541 -0
- agentops/instrumentation/providers/anthropic/attributes/tools.py +231 -0
- agentops/instrumentation/providers/anthropic/event_handler_wrapper.py +90 -0
- agentops/instrumentation/providers/anthropic/instrumentor.py +146 -0
- agentops/instrumentation/providers/anthropic/stream_wrapper.py +436 -0
- agentops/instrumentation/providers/google_genai/README.md +33 -0
- agentops/instrumentation/providers/google_genai/__init__.py +24 -0
- agentops/instrumentation/providers/google_genai/attributes/__init__.py +25 -0
- agentops/instrumentation/providers/google_genai/attributes/chat.py +125 -0
- agentops/instrumentation/providers/google_genai/attributes/common.py +88 -0
- agentops/instrumentation/providers/google_genai/attributes/model.py +284 -0
- agentops/instrumentation/providers/google_genai/instrumentor.py +170 -0
- agentops/instrumentation/providers/google_genai/stream_wrapper.py +238 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/__init__.py +28 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/attributes/__init__.py +27 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/attributes/attributes.py +277 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/attributes/common.py +104 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/instrumentor.py +162 -0
- agentops/instrumentation/providers/ibm_watsonx_ai/stream_wrapper.py +302 -0
- agentops/instrumentation/providers/mem0/__init__.py +45 -0
- agentops/instrumentation/providers/mem0/common.py +377 -0
- agentops/instrumentation/providers/mem0/instrumentor.py +270 -0
- agentops/instrumentation/providers/mem0/memory.py +430 -0
- agentops/instrumentation/providers/openai/__init__.py +21 -0
- agentops/instrumentation/providers/openai/attributes/__init__.py +7 -0
- agentops/instrumentation/providers/openai/attributes/common.py +55 -0
- agentops/instrumentation/providers/openai/attributes/response.py +607 -0
- agentops/instrumentation/providers/openai/config.py +36 -0
- agentops/instrumentation/providers/openai/instrumentor.py +312 -0
- agentops/instrumentation/providers/openai/stream_wrapper.py +941 -0
- agentops/instrumentation/providers/openai/utils.py +44 -0
- agentops/instrumentation/providers/openai/v0.py +176 -0
- agentops/instrumentation/providers/openai/v0_wrappers.py +483 -0
- agentops/instrumentation/providers/openai/wrappers/__init__.py +30 -0
- agentops/instrumentation/providers/openai/wrappers/assistant.py +277 -0
- agentops/instrumentation/providers/openai/wrappers/chat.py +259 -0
- agentops/instrumentation/providers/openai/wrappers/completion.py +109 -0
- agentops/instrumentation/providers/openai/wrappers/embeddings.py +94 -0
- agentops/instrumentation/providers/openai/wrappers/image_gen.py +75 -0
- agentops/instrumentation/providers/openai/wrappers/responses.py +191 -0
- agentops/instrumentation/providers/openai/wrappers/shared.py +81 -0
- agentops/instrumentation/utilities/concurrent_futures/__init__.py +10 -0
- agentops/instrumentation/utilities/concurrent_futures/instrumentation.py +206 -0
- agentops/integration/callbacks/dspy/__init__.py +11 -0
- agentops/integration/callbacks/dspy/callback.py +471 -0
- agentops/integration/callbacks/langchain/README.md +59 -0
- agentops/integration/callbacks/langchain/__init__.py +15 -0
- agentops/integration/callbacks/langchain/callback.py +791 -0
- agentops/integration/callbacks/langchain/utils.py +54 -0
- agentops/legacy/crewai.md +121 -0
- agentops/logging/instrument_logging.py +4 -0
- agentops/sdk/README.md +220 -0
- agentops/sdk/core.py +75 -32
- agentops/sdk/descriptors/classproperty.py +28 -0
- agentops/sdk/exporters.py +152 -33
- agentops/semconv/README.md +125 -0
- agentops/semconv/span_kinds.py +0 -2
- agentops/validation.py +102 -63
- {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/METADATA +30 -40
- mseep_agentops-0.4.23.dist-info/RECORD +178 -0
- {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/WHEEL +1 -2
- mseep_agentops-0.4.18.dist-info/RECORD +0 -94
- mseep_agentops-0.4.18.dist-info/top_level.txt +0 -2
- tests/conftest.py +0 -10
- tests/unit/client/__init__.py +0 -1
- tests/unit/client/test_http_adapter.py +0 -221
- tests/unit/client/test_http_client.py +0 -206
- tests/unit/conftest.py +0 -54
- tests/unit/sdk/__init__.py +0 -1
- tests/unit/sdk/instrumentation_tester.py +0 -207
- tests/unit/sdk/test_attributes.py +0 -392
- tests/unit/sdk/test_concurrent_instrumentation.py +0 -468
- tests/unit/sdk/test_decorators.py +0 -763
- tests/unit/sdk/test_exporters.py +0 -241
- tests/unit/sdk/test_factory.py +0 -1188
- tests/unit/sdk/test_internal_span_processor.py +0 -397
- tests/unit/sdk/test_resource_attributes.py +0 -35
- tests/unit/test_config.py +0 -82
- tests/unit/test_context_manager.py +0 -777
- tests/unit/test_events.py +0 -27
- tests/unit/test_host_env.py +0 -54
- tests/unit/test_init_py.py +0 -501
- tests/unit/test_serialization.py +0 -433
- tests/unit/test_session.py +0 -676
- tests/unit/test_user_agent.py +0 -34
- tests/unit/test_validation.py +0 -405
- {tests → agentops/instrumentation/agentic/openai_agents/attributes}/__init__.py +0 -0
- /tests/unit/__init__.py → /agentops/instrumentation/providers/openai/attributes/tools.py +0 -0
- {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
from .instrumentor import HaystackInstrumentor # noqa: F401
|
@@ -0,0 +1,186 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
from opentelemetry.trace import SpanKind
|
3
|
+
from opentelemetry.instrumentation.utils import unwrap
|
4
|
+
from wrapt import wrap_function_wrapper
|
5
|
+
|
6
|
+
from agentops.instrumentation.common import (
|
7
|
+
CommonInstrumentor,
|
8
|
+
InstrumentorConfig,
|
9
|
+
StandardMetrics,
|
10
|
+
create_wrapper_factory,
|
11
|
+
create_span,
|
12
|
+
SpanAttributeManager,
|
13
|
+
)
|
14
|
+
from agentops.semconv import SpanAttributes
|
15
|
+
|
16
|
+
|
17
|
+
_instruments = ("haystack-ai >= 2.0.0",)
|
18
|
+
|
19
|
+
|
20
|
+
class HaystackInstrumentor(CommonInstrumentor):
|
21
|
+
def __init__(self):
|
22
|
+
config = InstrumentorConfig(
|
23
|
+
library_name="haystack",
|
24
|
+
library_version="2",
|
25
|
+
wrapped_methods=[],
|
26
|
+
metrics_enabled=False,
|
27
|
+
dependencies=_instruments,
|
28
|
+
)
|
29
|
+
super().__init__(config)
|
30
|
+
self._attribute_manager = None
|
31
|
+
|
32
|
+
def _initialize(self, **kwargs):
|
33
|
+
application_name = kwargs.get("application_name", "default_application")
|
34
|
+
environment = kwargs.get("environment", "default_environment")
|
35
|
+
self._attribute_manager = SpanAttributeManager(
|
36
|
+
service_name=application_name, deployment_environment=environment
|
37
|
+
)
|
38
|
+
|
39
|
+
def _create_metrics(self, meter) -> Dict[str, Any]:
|
40
|
+
return StandardMetrics.create_standard_metrics(meter)
|
41
|
+
|
42
|
+
def _custom_wrap(self, **kwargs):
|
43
|
+
attr_manager = self._attribute_manager
|
44
|
+
|
45
|
+
wrap_function_wrapper(
|
46
|
+
"haystack.components.generators.openai",
|
47
|
+
"OpenAIGenerator.run",
|
48
|
+
create_wrapper_factory(_wrap_haystack_run_impl, self._metrics, attr_manager)(self._tracer),
|
49
|
+
)
|
50
|
+
|
51
|
+
wrap_function_wrapper(
|
52
|
+
"haystack.components.generators.chat",
|
53
|
+
"AzureOpenAIChatGenerator.run",
|
54
|
+
create_wrapper_factory(_wrap_haystack_run_impl, self._metrics, attr_manager)(self._tracer),
|
55
|
+
)
|
56
|
+
|
57
|
+
try:
|
58
|
+
wrap_function_wrapper(
|
59
|
+
"haystack.components.generators.openai",
|
60
|
+
"OpenAIGenerator.stream",
|
61
|
+
create_wrapper_factory(_wrap_haystack_stream_impl, self._metrics, attr_manager)(self._tracer),
|
62
|
+
)
|
63
|
+
except Exception:
|
64
|
+
pass
|
65
|
+
|
66
|
+
try:
|
67
|
+
wrap_function_wrapper(
|
68
|
+
"haystack.components.generators.chat",
|
69
|
+
"AzureOpenAIChatGenerator.stream",
|
70
|
+
create_wrapper_factory(_wrap_haystack_stream_impl, self._metrics, attr_manager)(self._tracer),
|
71
|
+
)
|
72
|
+
except Exception:
|
73
|
+
pass
|
74
|
+
|
75
|
+
def _custom_unwrap(self, **kwargs):
|
76
|
+
unwrap("haystack.components.generators.openai", "OpenAIGenerator.run")
|
77
|
+
unwrap("haystack.components.generators.chat", "AzureOpenAIChatGenerator.run")
|
78
|
+
try:
|
79
|
+
unwrap("haystack.components.generators.openai", "OpenAIGenerator.stream")
|
80
|
+
except Exception:
|
81
|
+
pass
|
82
|
+
try:
|
83
|
+
unwrap("haystack.components.generators.chat", "AzureOpenAIChatGenerator.stream")
|
84
|
+
except Exception:
|
85
|
+
pass
|
86
|
+
|
87
|
+
|
88
|
+
def _first_non_empty_text(value):
|
89
|
+
if isinstance(value, list) and value:
|
90
|
+
return _first_non_empty_text(value[0])
|
91
|
+
if isinstance(value, dict):
|
92
|
+
if "content" in value:
|
93
|
+
return str(value["content"])
|
94
|
+
if "text" in value:
|
95
|
+
return str(value["text"])
|
96
|
+
if "replies" in value and value["replies"]:
|
97
|
+
return str(value["replies"][0])
|
98
|
+
if value is None:
|
99
|
+
return None
|
100
|
+
return str(value)
|
101
|
+
|
102
|
+
|
103
|
+
def _extract_prompt(args, kwargs):
|
104
|
+
if "prompt" in kwargs:
|
105
|
+
return kwargs.get("prompt")
|
106
|
+
if "messages" in kwargs:
|
107
|
+
return kwargs.get("messages")
|
108
|
+
if args:
|
109
|
+
return args[0]
|
110
|
+
return None
|
111
|
+
|
112
|
+
|
113
|
+
def _get_model_name(instance):
|
114
|
+
for attr in ("model", "model_name", "deployment_name", "deployment"):
|
115
|
+
if hasattr(instance, attr):
|
116
|
+
val = getattr(instance, attr)
|
117
|
+
if val:
|
118
|
+
return str(val)
|
119
|
+
return None
|
120
|
+
|
121
|
+
|
122
|
+
def _wrap_haystack_run_impl(tracer, metrics, attr_manager, wrapped, instance, args, kwargs):
|
123
|
+
model = _get_model_name(instance)
|
124
|
+
with create_span(
|
125
|
+
tracer,
|
126
|
+
"haystack.generator.run",
|
127
|
+
kind=SpanKind.CLIENT,
|
128
|
+
attributes={
|
129
|
+
SpanAttributes.LLM_SYSTEM: "haystack",
|
130
|
+
"gen_ai.model": model,
|
131
|
+
SpanAttributes.LLM_REQUEST_STREAMING: False,
|
132
|
+
},
|
133
|
+
attribute_manager=attr_manager,
|
134
|
+
) as span:
|
135
|
+
prompt = _extract_prompt(args, kwargs)
|
136
|
+
prompt_text = _first_non_empty_text(prompt)
|
137
|
+
if prompt_text:
|
138
|
+
span.set_attribute("gen_ai.prompt.0.content", prompt_text[:500])
|
139
|
+
|
140
|
+
result = wrapped(*args, **kwargs)
|
141
|
+
|
142
|
+
reply_text = None
|
143
|
+
if isinstance(result, dict):
|
144
|
+
reply_text = _first_non_empty_text(result.get("replies"))
|
145
|
+
if not reply_text:
|
146
|
+
reply_text = _first_non_empty_text(result)
|
147
|
+
else:
|
148
|
+
reply_text = _first_non_empty_text(result)
|
149
|
+
|
150
|
+
if reply_text:
|
151
|
+
span.set_attribute("gen_ai.response.0.content", str(reply_text)[:500])
|
152
|
+
|
153
|
+
return result
|
154
|
+
|
155
|
+
|
156
|
+
def _wrap_haystack_stream_impl(tracer, metrics, attr_manager, wrapped, instance, args, kwargs):
|
157
|
+
model = _get_model_name(instance)
|
158
|
+
with create_span(
|
159
|
+
tracer,
|
160
|
+
"haystack.generator.stream",
|
161
|
+
kind=SpanKind.CLIENT,
|
162
|
+
attributes={
|
163
|
+
SpanAttributes.LLM_SYSTEM: "haystack",
|
164
|
+
"gen_ai.model": model,
|
165
|
+
SpanAttributes.LLM_REQUEST_STREAMING: True,
|
166
|
+
},
|
167
|
+
attribute_manager=attr_manager,
|
168
|
+
) as span:
|
169
|
+
prompt = _extract_prompt(args, kwargs)
|
170
|
+
prompt_text = _first_non_empty_text(prompt)
|
171
|
+
if prompt_text:
|
172
|
+
span.set_attribute("gen_ai.prompt.0.content", prompt_text[:500])
|
173
|
+
|
174
|
+
out = wrapped(*args, **kwargs)
|
175
|
+
|
176
|
+
try:
|
177
|
+
chunk_count = 0
|
178
|
+
for chunk in out:
|
179
|
+
chunk_count += 1
|
180
|
+
last_text = _first_non_empty_text(chunk)
|
181
|
+
if last_text:
|
182
|
+
span.set_attribute("gen_ai.response.0.content", str(last_text)[:500])
|
183
|
+
yield chunk
|
184
|
+
span.set_attribute("gen_ai.response.chunk_count", chunk_count)
|
185
|
+
except TypeError:
|
186
|
+
return out
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from typing import Dict, Any
|
2
|
+
import json
|
3
|
+
|
4
|
+
|
5
|
+
def ensure_no_none_values(attributes: Dict[str, Any]) -> Dict[str, Any]:
|
6
|
+
return {k: v for k, v in attributes.items() if v is not None}
|
7
|
+
|
8
|
+
|
9
|
+
def set_graph_attributes(span: Any, graph_nodes: list = None, graph_edges: list = None) -> None:
|
10
|
+
if graph_nodes:
|
11
|
+
span.set_attribute("langgraph.graph.nodes", json.dumps(graph_nodes))
|
12
|
+
span.set_attribute("langgraph.graph.node_count", len(graph_nodes))
|
13
|
+
|
14
|
+
for i, node in enumerate(graph_nodes):
|
15
|
+
span.set_attribute(f"langgraph.node.{i}.name", node)
|
16
|
+
span.set_attribute(f"langgraph.node.{i}.type", "unknown")
|
17
|
+
|
18
|
+
if graph_edges:
|
19
|
+
span.set_attribute("langgraph.graph.edges", json.dumps(graph_edges))
|
20
|
+
span.set_attribute("langgraph.graph.edge_count", len(graph_edges))
|
21
|
+
|
22
|
+
for i, edge in enumerate(graph_edges):
|
23
|
+
parts = edge.split("->")
|
24
|
+
if len(parts) == 2:
|
25
|
+
span.set_attribute(f"langgraph.edge.{i}.source", parts[0])
|
26
|
+
span.set_attribute(f"langgraph.edge.{i}.target", parts[1])
|
27
|
+
|
28
|
+
|
29
|
+
def extract_messages_from_input(input_data: Any) -> list:
|
30
|
+
if isinstance(input_data, dict) and "messages" in input_data:
|
31
|
+
return input_data["messages"]
|
32
|
+
return []
|
33
|
+
|
34
|
+
|
35
|
+
def extract_messages_from_output(output_data: Any) -> list:
|
36
|
+
if isinstance(output_data, dict) and "messages" in output_data:
|
37
|
+
return output_data["messages"]
|
38
|
+
return []
|
39
|
+
|
40
|
+
|
41
|
+
def get_message_content(message: Any) -> str:
|
42
|
+
if hasattr(message, "content"):
|
43
|
+
return str(message.content)
|
44
|
+
return ""
|
45
|
+
|
46
|
+
|
47
|
+
def get_message_role(message: Any) -> str:
|
48
|
+
if hasattr(message, "role"):
|
49
|
+
return message.role
|
50
|
+
elif hasattr(message, "type"):
|
51
|
+
return message.type
|
52
|
+
elif hasattr(message, "__class__"):
|
53
|
+
return message.__class__.__name__.replace("Message", "").lower()
|
54
|
+
return "unknown"
|