agentreplay 0.1.2__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.
@@ -0,0 +1,81 @@
1
+ # Copyright 2025 Sushanth (https://github.com/sushanthpy)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Agentreplay Python SDK - Agent Trace Engine for LLM Agents."""
16
+
17
+ from agentreplay.client import AgentreplayClient
18
+ from agentreplay.models import SpanType, AgentFlowEdge
19
+ from agentreplay.span import Span
20
+ from agentreplay.config import AgentreplayConfig, get_config, set_config, reset_config
21
+ from agentreplay.batching import BatchingAgentreplayClient
22
+ from agentreplay.session import Session
23
+ from agentreplay.retry import retry_with_backoff
24
+ from agentreplay.exceptions import (
25
+ AgentreplayError,
26
+ AuthenticationError,
27
+ RateLimitError,
28
+ ServerError,
29
+ ValidationError,
30
+ NotFoundError,
31
+ NetworkError,
32
+ )
33
+
34
+ # Agent Context Tracking
35
+ from agentreplay.context import AgentContext
36
+
37
+ # Auto-instrumentation (Pure OpenTelemetry)
38
+ from agentreplay.auto_instrument import auto_instrument, setup_instrumentation
39
+
40
+ # OTEL Bridge & Bootstrap
41
+ from agentreplay.bootstrap import init_otel_instrumentation, is_initialized
42
+ from agentreplay.otel_bridge import get_tracer
43
+
44
+ __version__ = "0.1.2"
45
+
46
+ __all__ = [
47
+ # Core client
48
+ "AgentreplayClient",
49
+ "BatchingAgentreplayClient",
50
+ # Models
51
+ "SpanType",
52
+ "AgentFlowEdge",
53
+ "Span",
54
+ # Configuration
55
+ "AgentreplayConfig",
56
+ "get_config",
57
+ "set_config",
58
+ "reset_config",
59
+ # Session management
60
+ "Session",
61
+ # Retry utilities
62
+ "retry_with_backoff",
63
+ # Agent Context
64
+ "AgentContext",
65
+ # Auto-instrumentation (Pure OpenTelemetry)
66
+ "auto_instrument",
67
+ "setup_instrumentation",
68
+ # OTEL Initialization
69
+ "init_otel_instrumentation",
70
+ "is_initialized",
71
+ # OTEL Bridge
72
+ "get_tracer",
73
+ # Exceptions
74
+ "AgentreplayError",
75
+ "AuthenticationError",
76
+ "RateLimitError",
77
+ "ServerError",
78
+ "ValidationError",
79
+ "NotFoundError",
80
+ "NetworkError",
81
+ ]
@@ -0,0 +1,237 @@
1
+ # Copyright 2025 Sushanth (https://github.com/sushanthpy)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Automatic instrumentation using OpenTelemetry.
16
+
17
+ This module provides zero-code observability by leveraging the official
18
+ OpenTelemetry instrumentation ecosystem. We don't maintain framework-specific
19
+ integrations - we use the community-maintained OTEL instrumentations.
20
+
21
+ Example:
22
+ >>> from agentreplay import auto_instrument
23
+ >>> auto_instrument("my-service")
24
+ >>>
25
+ >>> # Now all instrumented libraries automatically emit spans!
26
+ >>> from openai import OpenAI
27
+ >>> client = OpenAI()
28
+ >>> response = client.chat.completions.create(...) # ✓ Traced via OTEL
29
+ """
30
+
31
+ from typing import Optional
32
+ import logging
33
+ import os
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+ _instrumented = False
38
+
39
+
40
+ def auto_instrument(
41
+ service_name: str,
42
+ otlp_endpoint: str = "localhost:47117",
43
+ tenant_id: int = 1,
44
+ project_id: int = 0,
45
+ capture_content: bool = True,
46
+ debug: bool = False,
47
+ ) -> None:
48
+ """Automatically instrument using OpenTelemetry.
49
+
50
+ Sets up OTLP exporter and automatically instruments all available
51
+ libraries using their official OTEL instrumentations.
52
+
53
+ Args:
54
+ service_name: Name of your service
55
+ otlp_endpoint: OTLP gRPC endpoint (default: localhost:47117)
56
+ tenant_id: Tenant ID (added to resource attributes)
57
+ project_id: Project ID (added to resource attributes)
58
+ capture_content: Capture LLM request/response content (default: True)
59
+ debug: Enable debug logging (default: False)
60
+ """
61
+ global _instrumented
62
+
63
+ if _instrumented:
64
+ logger.warning("Already instrumented. Skipping.")
65
+ return
66
+
67
+ if debug:
68
+ logging.basicConfig(level=logging.DEBUG)
69
+ logger.setLevel(logging.DEBUG)
70
+
71
+ logger.info(f"🚀 Setting up Agentreplay OpenTelemetry for service: {service_name}")
72
+
73
+ try:
74
+ # Use the otel_bridge to set up tracer provider
75
+ from agentreplay.otel_bridge import setup_tracer_provider
76
+
77
+ setup_tracer_provider(
78
+ service_name=service_name,
79
+ otlp_endpoint=otlp_endpoint,
80
+ tenant_id=tenant_id,
81
+ project_id=project_id,
82
+ debug=debug,
83
+ )
84
+
85
+ logger.info(f"✓ OTLP exporter configured: {otlp_endpoint}")
86
+
87
+ # Set environment for OpenAI instrumentation
88
+ if capture_content:
89
+ os.environ["AGENTREPLAY_CAPTURE_CONTENT"] = "true"
90
+ else:
91
+ os.environ["AGENTREPLAY_CAPTURE_CONTENT"] = "false"
92
+
93
+ # Auto-discover and instrument everything
94
+ _auto_instrument_all()
95
+
96
+ _instrumented = True
97
+ logger.info("✅ Auto-instrumentation complete")
98
+
99
+ except Exception as e:
100
+ logger.error(f"❌ Failed to setup OpenTelemetry: {e}")
101
+ raise
102
+
103
+
104
+ def _auto_instrument_all():
105
+ """Auto-instrument all available libraries using official OTEL instrumentations."""
106
+
107
+ instrumented = []
108
+
109
+ # Enable content capture for GenAI instrumentations (OTEL standard)
110
+ import os
111
+ capture_content = os.getenv("AGENTREPLAY_CAPTURE_CONTENT", "true").lower() in {"1", "true", "yes"}
112
+ if capture_content:
113
+ os.environ["OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"] = "true"
114
+
115
+ # Try OpenAI
116
+ try:
117
+ from opentelemetry.instrumentation.openai import OpenAIInstrumentor
118
+ OpenAIInstrumentor().instrument()
119
+ instrumented.append("OpenAI")
120
+ except ImportError:
121
+ pass
122
+ except Exception as e:
123
+ logger.debug(f"OpenAI instrumentation failed: {e}")
124
+
125
+ # Try Anthropic
126
+ try:
127
+ from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
128
+ AnthropicInstrumentor().instrument()
129
+ instrumented.append("Anthropic")
130
+ except ImportError:
131
+ pass
132
+ except Exception as e:
133
+ logger.debug(f"Anthropic instrumentation failed: {e}")
134
+
135
+ # Try LangChain - use custom Agentreplay callback handler for hierarchy
136
+ try:
137
+ from agentreplay.langchain_tracer import get_agentreplay_callback
138
+
139
+ callback = get_agentreplay_callback()
140
+ if callback:
141
+ # Register globally for all LangChain operations
142
+ import langchain_core.callbacks.manager as manager
143
+ if hasattr(manager, '_default_callback_handlers'):
144
+ if not hasattr(manager._default_callback_handlers, '__iter__'):
145
+ manager._default_callback_handlers = []
146
+ manager._default_callback_handlers.append(callback)
147
+ instrumented.append("LangChain")
148
+ except ImportError:
149
+ pass # LangChain not installed
150
+ except Exception as e:
151
+ logger.debug(f"LangChain instrumentation failed: {e}")
152
+
153
+ # Try LlamaIndex
154
+ try:
155
+ from opentelemetry.instrumentation.llamaindex import LlamaIndexInstrumentor
156
+ LlamaIndexInstrumentor().instrument()
157
+ instrumented.append("LlamaIndex")
158
+ except ImportError:
159
+ pass
160
+ except Exception as e:
161
+ logger.debug(f"LlamaIndex instrumentation failed: {e}")
162
+
163
+ # Try HTTP clients (requests, httpx, urllib3)
164
+ try:
165
+ from opentelemetry.instrumentation.requests import RequestsInstrumentor
166
+ RequestsInstrumentor().instrument()
167
+ instrumented.append("requests")
168
+ except ImportError:
169
+ pass
170
+ except Exception as e:
171
+ logger.debug(f"requests instrumentation failed: {e}")
172
+
173
+ try:
174
+ from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
175
+ HTTPXClientInstrumentor().instrument()
176
+ instrumented.append("httpx")
177
+ except ImportError:
178
+ pass
179
+ except Exception as e:
180
+ logger.debug(f"httpx instrumentation failed: {e}")
181
+
182
+ if instrumented:
183
+ logger.info(f"✓ Instrumented: {', '.join(instrumented)}")
184
+ else:
185
+ logger.warning("No instrumentable libraries found. Install opentelemetry-instrumentation-* packages.")
186
+
187
+
188
+ def setup_instrumentation(
189
+ service_name: Optional[str] = None,
190
+ otlp_endpoint: Optional[str] = None,
191
+ tenant_id: Optional[int] = None,
192
+ project_id: Optional[int] = None,
193
+ capture_content: Optional[bool] = None,
194
+ debug: Optional[bool] = None,
195
+ ) -> None:
196
+ """Setup instrumentation with environment variable fallbacks.
197
+
198
+ This is a convenience wrapper around auto_instrument that reads from
199
+ environment variables if parameters aren't provided.
200
+
201
+ Args:
202
+ service_name: Service name (default: from env or 'default-service')
203
+ otlp_endpoint: OTLP endpoint (default: from env or 'localhost:47117')
204
+ tenant_id: Tenant ID (default: from env or 1)
205
+ project_id: Project ID (default: from env or 0)
206
+ capture_content: Capture LLM content (default: from env or True)
207
+ debug: Enable debug logging (default: from env or False)
208
+ """
209
+ # Read from environment
210
+ service_name = service_name or os.getenv("AGENTREPLAY_SERVICE_NAME", "default-service")
211
+ otlp_endpoint = otlp_endpoint or os.getenv("AGENTREPLAY_OTLP_ENDPOINT", "localhost:47117")
212
+
213
+ if tenant_id is None:
214
+ tenant_id = int(os.getenv("AGENTREPLAY_TENANT_ID", "1"))
215
+
216
+ if project_id is None:
217
+ project_id = int(os.getenv("AGENTREPLAY_PROJECT_ID", "0"))
218
+
219
+ if capture_content is None:
220
+ capture_content = os.getenv("AGENTREPLAY_CAPTURE_CONTENT", "true").lower() in {
221
+ "1", "true", "yes"
222
+ }
223
+
224
+ if debug is None:
225
+ debug = os.getenv("AGENTREPLAY_DEBUG", "false").lower() in {"1", "true", "yes"}
226
+
227
+ auto_instrument(
228
+ service_name=service_name,
229
+ otlp_endpoint=otlp_endpoint,
230
+ tenant_id=tenant_id,
231
+ project_id=project_id,
232
+ capture_content=capture_content,
233
+ debug=debug,
234
+ )
235
+
236
+
237
+ __all__ = ["auto_instrument", "setup_instrumentation"]