ragaai-catalyst 2.1.4.1b1__py3-none-any.whl → 2.1.5b1__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.
@@ -61,6 +61,7 @@ class LLMTracerMixin:
61
61
  # Add auto_instrument options
62
62
  self.auto_instrument_llm = False
63
63
  self.auto_instrument_user_interaction = False
64
+ self.auto_instrument_file_io = False
64
65
  self.auto_instrument_network = False
65
66
 
66
67
  def instrument_llm_calls(self):
@@ -117,6 +118,10 @@ class LLMTracerMixin:
117
118
  def instrument_network_calls(self):
118
119
  """Enable network instrumentation for LLM calls"""
119
120
  self.auto_instrument_network = True
121
+
122
+ def instrument_file_io_calls(self):
123
+ """Enable file IO instrumentation for LLM calls"""
124
+ self.auto_instrument_file_io = True
120
125
 
121
126
  def patch_openai_methods(self, module):
122
127
  try:
@@ -334,7 +339,17 @@ class LLMTracerMixin:
334
339
 
335
340
  interactions = []
336
341
  if self.auto_instrument_user_interaction:
337
- interactions = self.component_user_interaction.get(component_id, [])
342
+ input_output_interactions = []
343
+ for interaction in self.component_user_interaction.get(component_id, []):
344
+ if interaction["interaction_type"] in ["input", "output"]:
345
+ input_output_interactions.append(interaction)
346
+ interactions.extend(input_output_interactions)
347
+ if self.auto_instrument_file_io:
348
+ file_io_interactions = []
349
+ for interaction in self.component_user_interaction.get(component_id, []):
350
+ if interaction["interaction_type"] in ["file_read", "file_write"]:
351
+ file_io_interactions.append(interaction)
352
+ interactions.extend(file_io_interactions)
338
353
 
339
354
  parameters_to_display = {}
340
355
  if "run_manager" in parameters:
@@ -475,7 +490,7 @@ class LLMTracerMixin:
475
490
  parameters=parameters,
476
491
  )
477
492
 
478
- # self.add_component(llm_component)
493
+ self.add_component(llm_component)
479
494
  self.llm_data = llm_component
480
495
 
481
496
  return result
@@ -84,27 +84,23 @@ class AgenticTracing(
84
84
  self.auto_instrument_custom = True
85
85
  else:
86
86
  # Set global active state
87
- self.is_active = (
88
- any(auto_instrumentation.values())
89
- if isinstance(auto_instrumentation, dict)
90
- else bool(auto_instrumentation)
91
- )
87
+ self.is_active = True
92
88
 
93
89
  # Set individual components
94
90
  if isinstance(auto_instrumentation, dict):
95
- self.auto_instrument_llm = auto_instrumentation.get("llm", False)
96
- self.auto_instrument_tool = auto_instrumentation.get("tool", False)
97
- self.auto_instrument_agent = auto_instrumentation.get("agent", False)
91
+ self.auto_instrument_llm = auto_instrumentation.get("llm", True)
92
+ self.auto_instrument_tool = auto_instrumentation.get("tool", True)
93
+ self.auto_instrument_agent = auto_instrumentation.get("agent", True)
98
94
  self.auto_instrument_user_interaction = auto_instrumentation.get(
99
- "user_interaction", False
95
+ "user_interaction", True
100
96
  )
101
97
  self.auto_instrument_file_io = auto_instrumentation.get(
102
- "file_io", False
98
+ "file_io", True
103
99
  )
104
100
  self.auto_instrument_network = auto_instrumentation.get(
105
- "network", False
101
+ "network", True
106
102
  )
107
- self.auto_instrument_custom = auto_instrumentation.get("custom", False)
103
+ self.auto_instrument_custom = auto_instrumentation.get("custom", True)
108
104
  else:
109
105
  # If boolean provided, apply to all components
110
106
  self.auto_instrument_llm = bool(auto_instrumentation)
@@ -137,13 +133,28 @@ class AgenticTracing(
137
133
  self.network_tracer.network_calls.copy()
138
134
  )
139
135
  self.network_tracer.network_calls = [] # Reset for next component
140
- # self.component_user_interaction[component_id] = [interaction for interaction in self.user_interaction_tracer.interactions if interaction.get('component_id') == component_id]
136
+
137
+ # Store user interactions for the component
141
138
  for interaction in self.user_interaction_tracer.interactions:
142
139
  interaction_component_id = interaction.get("component_id")
143
140
  if interaction_component_id not in self.component_user_interaction:
144
141
  self.component_user_interaction[interaction_component_id] = []
145
142
  if interaction not in self.component_user_interaction[interaction_component_id]:
146
143
  self.component_user_interaction[interaction_component_id].append(interaction)
144
+
145
+ # Only reset component_id if it matches the current one
146
+ # This ensures we don't reset a parent's component_id when a child component ends
147
+ if self.current_component_id.get() == component_id:
148
+ # Get the parent agent's component_id if it exists
149
+ parent_agent_id = self.current_agent_id.get()
150
+ # If there's a parent agent, set the component_id back to the parent's
151
+ if parent_agent_id:
152
+ self.current_component_id.set(parent_agent_id)
153
+ self.user_interaction_tracer.component_id.set(parent_agent_id)
154
+ else:
155
+ # Only reset to None if there's no parent
156
+ self.current_component_id.set(None)
157
+ self.user_interaction_tracer.component_id.set(None)
147
158
 
148
159
  def start(self):
149
160
  """Start tracing"""
@@ -155,9 +166,6 @@ class AgenticTracing(
155
166
  self.user_interaction_tracer.trace_id.set(self.trace_id)
156
167
  self.user_interaction_tracer.tracer = self
157
168
  self.user_interaction_tracer.component_id.set(self.current_component_id.get())
158
- builtins.print = self.user_interaction_tracer.traced_print
159
- builtins.input = self.user_interaction_tracer.traced_input
160
- builtins.open = self.user_interaction_tracer.traced_open
161
169
 
162
170
  # Start base tracer (includes system info and resource monitoring)
163
171
  super().start()
@@ -179,11 +187,12 @@ class AgenticTracing(
179
187
  self.instrument_custom_calls()
180
188
 
181
189
  if self.auto_instrument_user_interaction:
182
-
183
190
  ToolTracerMixin.instrument_user_interaction_calls(self)
184
191
  LLMTracerMixin.instrument_user_interaction_calls(self)
185
192
  AgentTracerMixin.instrument_user_interaction_calls(self)
186
193
  CustomTracerMixin.instrument_user_interaction_calls(self)
194
+ builtins.print = self.user_interaction_tracer.traced_print
195
+ builtins.input = self.user_interaction_tracer.traced_input
187
196
 
188
197
  if self.auto_instrument_network:
189
198
  ToolTracerMixin.instrument_network_calls(self)
@@ -191,9 +200,12 @@ class AgenticTracing(
191
200
  AgentTracerMixin.instrument_network_calls(self)
192
201
  CustomTracerMixin.instrument_network_calls(self)
193
202
 
194
- # These will be implemented later
195
- # if self.auto_instrument_file_io:
196
- # self.instrument_file_io_calls()
203
+ if self.auto_instrument_file_io:
204
+ ToolTracerMixin.instrument_file_io_calls(self)
205
+ LLMTracerMixin.instrument_file_io_calls(self)
206
+ AgentTracerMixin.instrument_file_io_calls(self)
207
+ CustomTracerMixin.instrument_file_io_calls(self)
208
+ builtins.open = self.user_interaction_tracer.traced_open
197
209
 
198
210
  def stop(self):
199
211
  """Stop tracing and save results"""
@@ -41,7 +41,7 @@ class NetworkTracer:
41
41
 
42
42
  # Extract protocol from URL
43
43
  protocol = "https" if url.startswith("https") else "http"
44
-
44
+
45
45
  self.network_calls.append(
46
46
  {
47
47
  "url": url,
@@ -57,11 +57,11 @@ class NetworkTracer:
57
57
  "parent_id": None, # Will be set by the component
58
58
  "request": {
59
59
  "headers": request_headers,
60
- "body": request_body[:1000] if request_body else None, # Limit to 1000 chars
60
+ "body": request_body if request_body else None,
61
61
  },
62
62
  "response": {
63
63
  "headers": response_headers,
64
- "body": response_body[:1000] if response_body else None, # Limit to 1000 chars
64
+ "body": response_body if response_body else None,
65
65
  },
66
66
  "error": str(error) if error else None,
67
67
  }
@@ -32,6 +32,7 @@ class ToolTracerMixin:
32
32
  # add auto_instrument option
33
33
  self.auto_instrument_tool = False
34
34
  self.auto_instrument_user_interaction = False
35
+ self.auto_instrument_file_io = False
35
36
  self.auto_instrument_network = False
36
37
 
37
38
  # take care of auto_instrument
@@ -40,6 +41,9 @@ class ToolTracerMixin:
40
41
 
41
42
  def instrument_user_interaction_calls(self):
42
43
  self.auto_instrument_user_interaction = True
44
+
45
+ def instrument_file_io_calls(self):
46
+ self.auto_instrument_file_io = True
43
47
 
44
48
  def instrument_network_calls(self):
45
49
  self.auto_instrument_network = True
@@ -133,6 +137,10 @@ class ToolTracerMixin:
133
137
  component_id = str(uuid.uuid4())
134
138
  hash_id = generate_unique_hash_simple(func)
135
139
 
140
+ # Set current tool name and store the token
141
+ name_token = self.current_tool_name.set(name)
142
+ id_token = self.current_tool_id.set(component_id)
143
+
136
144
  # Start tracking network calls for this component
137
145
  self.start_component(component_id)
138
146
 
@@ -191,6 +199,12 @@ class ToolTracerMixin:
191
199
  self.add_component(tool_component)
192
200
 
193
201
  raise
202
+ finally:
203
+ # Reset the tool name and id context
204
+ if name_token:
205
+ self.current_tool_name.reset(name_token)
206
+ if id_token:
207
+ self.current_tool_id.reset(id_token)
194
208
 
195
209
  async def _trace_tool_execution(
196
210
  self, func, name, tool_type, version, *args, **kwargs
@@ -207,6 +221,10 @@ class ToolTracerMixin:
207
221
  component_id = str(uuid.uuid4())
208
222
  hash_id = generate_unique_hash_simple(func)
209
223
 
224
+ # Set current tool name and store the token
225
+ name_token = self.current_tool_name.set(name)
226
+ id_token = self.current_tool_id.set(component_id)
227
+
210
228
  self.start_component(component_id)
211
229
  try:
212
230
  # Execute the tool
@@ -256,6 +274,12 @@ class ToolTracerMixin:
256
274
  self.add_component(tool_component)
257
275
 
258
276
  raise
277
+ finally:
278
+ # Reset the tool name and id context
279
+ if name_token:
280
+ self.current_tool_name.reset(name_token)
281
+ if id_token:
282
+ self.current_tool_id.reset(id_token)
259
283
 
260
284
  def create_tool_component(self, **kwargs):
261
285
  """Create a tool component according to the data structure"""
@@ -264,9 +288,19 @@ class ToolTracerMixin:
264
288
  network_calls = self.component_network_calls.get(kwargs["component_id"], [])
265
289
  interactions = []
266
290
  if self.auto_instrument_user_interaction:
267
- interactions = self.component_user_interaction.get(
268
- kwargs["component_id"], []
269
- )
291
+ input_output_interactions = []
292
+ for interaction in self.component_user_interaction.get(kwargs["component_id"], []):
293
+ if interaction["interaction_type"] in ["input", "output"]:
294
+ input_output_interactions.append(interaction)
295
+ if input_output_interactions!=[]:
296
+ interactions.extend(input_output_interactions)
297
+ if self.auto_instrument_file_io:
298
+ file_io_interactions = []
299
+ for interaction in self.component_user_interaction.get(kwargs["component_id"], []):
300
+ if interaction["interaction_type"] in ["file_read", "file_write"]:
301
+ file_io_interactions.append(interaction)
302
+ if file_io_interactions!=[]:
303
+ interactions.extend(file_io_interactions)
270
304
 
271
305
  # Get tags, metrics
272
306
  name = kwargs["name"]
@@ -2063,7 +2063,9 @@
2063
2063
  "input_cost_per_token": 5.9e-07,
2064
2064
  "output_cost_per_token": 7.9e-07,
2065
2065
  "litellm_provider": "groq",
2066
- "mode": "chat"
2066
+ "mode": "chat",
2067
+ "supports_function_calling": true,
2068
+ "supports_response_schema": true
2067
2069
  },
2068
2070
  "groq/llama-3.3-70b-specdec": {
2069
2071
  "max_tokens": 8192,
@@ -4605,6 +4607,20 @@
4605
4607
  "litellm_provider": "replicate",
4606
4608
  "mode": "chat"
4607
4609
  },
4610
+ "openrouter/deepseek/deepseek-r1": {
4611
+ "max_tokens": 8192,
4612
+ "max_input_tokens": 64000,
4613
+ "max_output_tokens": 8192,
4614
+ "input_cost_per_token": 5.5e-07,
4615
+ "input_cost_per_token_cache_hit": 1.4e-07,
4616
+ "output_cost_per_token": 2.19e-06,
4617
+ "litellm_provider": "openrouter",
4618
+ "mode": "chat",
4619
+ "supports_function_calling": true,
4620
+ "supports_assistant_prefill": true,
4621
+ "supports_tool_choice": true,
4622
+ "supports_prompt_caching": true
4623
+ },
4608
4624
  "openrouter/deepseek/deepseek-chat": {
4609
4625
  "max_tokens": 8192,
4610
4626
  "max_input_tokens": 66000,
@@ -5,7 +5,6 @@ import re
5
5
  import ast
6
6
  import importlib.util
7
7
  import json
8
- import astor
9
8
  import ipynbname
10
9
  import sys
11
10
 
@@ -74,12 +73,14 @@ class PackageUsageRemover(ast.NodeTransformer):
74
73
  def remove_package_code(source_code: str, package_name: str) -> str:
75
74
  try:
76
75
  tree = ast.parse(source_code)
77
- transformer = PackageUsageRemover(package_name)
78
- modified_tree = transformer.visit(tree)
79
- modified_code = astor.to_source(modified_tree)
76
+ remover = PackageUsageRemover(package_name)
77
+ modified_tree = remover.visit(tree)
78
+ modified_code = ast.unparse(modified_tree)
79
+
80
80
  return modified_code
81
81
  except Exception as e:
82
- raise Exception(f"Error processing source code: {str(e)}")
82
+ logger.error(f"Error in remove_package_code: {e}")
83
+ return source_code
83
84
 
84
85
  class JupyterNotebookHandler:
85
86
  @staticmethod
@@ -452,4 +453,3 @@ if __name__ == "__main__":
452
453
  hash_id, zip_path = zip_list_of_unique_files(filepaths)
453
454
  print(f"Created zip file: {zip_path}")
454
455
  print(f"Hash ID: {hash_id}")
455
-
@@ -0,0 +1,313 @@
1
+ """
2
+ Distributed tracing functionality for RagaAI Catalyst.
3
+ Provides simplified initialization and decorator-based tracing.
4
+ """
5
+
6
+ import os
7
+ import threading
8
+ from typing import Optional, Dict, Any, List
9
+ from functools import wraps
10
+ from contextlib import contextmanager
11
+ import uuid
12
+ from datetime import datetime
13
+ import asyncio
14
+
15
+ from .tracer import Tracer
16
+ from ..ragaai_catalyst import RagaAICatalyst
17
+
18
+ # Global state
19
+ _global_tracer: Optional[Tracer] = None
20
+ _global_catalyst: Optional[RagaAICatalyst] = None
21
+ _tracer_lock = threading.Lock()
22
+ _active_spans = threading.local()
23
+
24
+ def get_current_tracer() -> Optional[Tracer]:
25
+ """Get the current global tracer instance."""
26
+ return _global_tracer
27
+
28
+ def get_current_catalyst() -> Optional[RagaAICatalyst]:
29
+ """Get the current global catalyst instance."""
30
+ return _global_catalyst
31
+
32
+ def init_tracing(
33
+ project_name: str = None,
34
+ dataset_name: str = None,
35
+ access_key: str = None,
36
+ secret_key: str = None,
37
+ base_url: str = None,
38
+ tracer: Tracer = None,
39
+ catalyst: RagaAICatalyst = None,
40
+ **kwargs
41
+ ) -> None:
42
+ """Initialize distributed tracing.
43
+
44
+ Args:
45
+ project_name: Project name for new tracer
46
+ dataset_name: Dataset name for new tracer
47
+ access_key: RagaAI Catalyst access key
48
+ secret_key: RagaAI Catalyst secret key
49
+ base_url: RagaAI Catalyst API base URL
50
+ tracer: Existing Tracer instance
51
+ catalyst: Existing RagaAICatalyst instance
52
+ **kwargs: Additional tracer configuration
53
+ """
54
+ global _global_tracer, _global_catalyst
55
+
56
+ with _tracer_lock:
57
+ if tracer and catalyst:
58
+ _global_tracer = tracer
59
+ _global_catalyst = catalyst
60
+ else:
61
+ # Use env vars as fallback
62
+ access_key = access_key or os.getenv("RAGAAI_CATALYST_ACCESS_KEY")
63
+ secret_key = secret_key or os.getenv("RAGAAI_CATALYST_SECRET_KEY")
64
+ base_url = base_url or os.getenv("RAGAAI_CATALYST_BASE_URL")
65
+
66
+ if not all([access_key, secret_key]):
67
+ raise ValueError(
68
+ "Missing required credentials. Either provide access_key and secret_key "
69
+ "or set RAGAAI_CATALYST_ACCESS_KEY and RAGAAI_CATALYST_SECRET_KEY environment variables."
70
+ )
71
+
72
+ _global_catalyst = RagaAICatalyst(
73
+ access_key=access_key,
74
+ secret_key=secret_key,
75
+ base_url=base_url
76
+ )
77
+
78
+ _global_tracer = Tracer(
79
+ project_name=project_name,
80
+ dataset_name=dataset_name,
81
+ **kwargs
82
+ )
83
+
84
+ def trace_agent(name: str = None, agent_type: str = "generic", version: str = "1.0.0", **kwargs):
85
+ """Decorator for tracing agent functions."""
86
+ def decorator(func):
87
+ is_async = asyncio.iscoroutinefunction(func)
88
+ span_name = name or func.__name__
89
+
90
+ @wraps(func)
91
+ async def async_wrapper(*args, **kwargs):
92
+ tracer = get_current_tracer()
93
+ if not tracer:
94
+ return await func(*args, **kwargs)
95
+
96
+ # Set current agent name and store the token
97
+ name_token = tracer.current_agent_name.set(span_name)
98
+
99
+ try:
100
+ # Use async agent tracing
101
+ return await tracer._trace_agent_execution(
102
+ func,
103
+ span_name,
104
+ agent_type,
105
+ version,
106
+ None, # capabilities
107
+ str(uuid.uuid4()), # hash_id
108
+ *args,
109
+ **kwargs
110
+ )
111
+ finally:
112
+ # Reset using the stored token
113
+ if name_token:
114
+ tracer.current_agent_name.reset(name_token)
115
+
116
+ @wraps(func)
117
+ def sync_wrapper(*args, **kwargs):
118
+ tracer = get_current_tracer()
119
+ if not tracer:
120
+ return func(*args, **kwargs)
121
+
122
+ # Set current agent name and store the token
123
+ name_token = tracer.current_agent_name.set(span_name)
124
+
125
+ try:
126
+ # Use synchronous agent tracing
127
+ return tracer._trace_sync_agent_execution(
128
+ func,
129
+ span_name,
130
+ agent_type,
131
+ version,
132
+ None, # capabilities
133
+ *args,
134
+ **kwargs
135
+ )
136
+ finally:
137
+ # Reset using the stored token
138
+ if name_token:
139
+ tracer.current_agent_name.reset(name_token)
140
+
141
+ return async_wrapper if is_async else sync_wrapper
142
+ return decorator
143
+
144
+ def trace_llm(name: str = None, model: str = None, **kwargs):
145
+ """Decorator for tracing LLM calls."""
146
+ def decorator(func):
147
+ is_async = asyncio.iscoroutinefunction(func)
148
+ span_name = name or func.__name__
149
+
150
+ @wraps(func)
151
+ async def async_wrapper(*args, **kwargs):
152
+ tracer = get_current_tracer()
153
+ if not tracer:
154
+ return await func(*args, **kwargs)
155
+
156
+ # Set current LLM name and store the token
157
+ name_token = tracer.current_llm_call_name.set(span_name)
158
+
159
+ try:
160
+ # Just execute the function within the current span
161
+ result = await func(*args, **kwargs)
162
+ return result
163
+ finally:
164
+ # Reset using the stored token
165
+ if name_token:
166
+ tracer.current_llm_call_name.reset(name_token)
167
+
168
+ @wraps(func)
169
+ def sync_wrapper(*args, **kwargs):
170
+ tracer = get_current_tracer()
171
+ if not tracer:
172
+ return func(*args, **kwargs)
173
+
174
+ # Set current LLM name and store the token
175
+ name_token = tracer.current_llm_call_name.set(span_name)
176
+
177
+ try:
178
+ # Just execute the function within the current span
179
+ result = func(*args, **kwargs)
180
+ return result
181
+ finally:
182
+ # Reset using the stored token
183
+ if name_token:
184
+ tracer.current_llm_call_name.reset(name_token)
185
+
186
+ return async_wrapper if is_async else sync_wrapper
187
+ return decorator
188
+
189
+
190
+ def trace_tool(name: str = None, tool_type: str = "generic", version: str = "1.0.0", **kwargs):
191
+ """Decorator for tracing tool functions."""
192
+ def decorator(func):
193
+ is_async = asyncio.iscoroutinefunction(func)
194
+ span_name = name or func.__name__
195
+
196
+ @wraps(func)
197
+ async def async_wrapper(*args, **kwargs):
198
+ tracer = get_current_tracer()
199
+ if not tracer:
200
+ return await func(*args, **kwargs)
201
+
202
+ # Set current tool name and store the token
203
+ name_token = tracer.current_tool_name.set(span_name)
204
+
205
+ try:
206
+ # Use async tool tracing
207
+ return await tracer._trace_tool_execution(
208
+ func,
209
+ span_name,
210
+ tool_type,
211
+ version,
212
+ *args,
213
+ **kwargs
214
+ )
215
+ finally:
216
+ # Reset using the stored token
217
+ if name_token:
218
+ tracer.current_tool_name.reset(name_token)
219
+
220
+ @wraps(func)
221
+ def sync_wrapper(*args, **kwargs):
222
+ tracer = get_current_tracer()
223
+ if not tracer:
224
+ return func(*args, **kwargs)
225
+
226
+ # Set current tool name and store the token
227
+ name_token = tracer.current_tool_name.set(span_name)
228
+
229
+ try:
230
+ # Use synchronous tool tracing
231
+ return tracer._trace_sync_tool_execution(
232
+ func,
233
+ span_name,
234
+ tool_type,
235
+ version,
236
+ *args,
237
+ **kwargs
238
+ )
239
+ finally:
240
+ # Reset using the stored token
241
+ if name_token:
242
+ tracer.current_tool_name.reset(name_token)
243
+
244
+ return async_wrapper if is_async else sync_wrapper
245
+ return decorator
246
+
247
+
248
+
249
+ def trace_custom(name: str = None, custom_type: str = "generic", version: str = "1.0.0", trace_variables: bool = False, **kwargs):
250
+ """Decorator for tracing custom functions."""
251
+ def decorator(func):
252
+ is_async = asyncio.iscoroutinefunction(func)
253
+
254
+ @wraps(func)
255
+ async def async_wrapper(*args, **kwargs):
256
+ tracer = get_current_tracer()
257
+ if not tracer:
258
+ return await func(*args, **kwargs)
259
+
260
+ # Use async tool tracing
261
+ return await tracer._trace_custom_execution(
262
+ func,
263
+ name or func.__name__,
264
+ custom_type,
265
+ version,
266
+ trace_variables,
267
+ *args,
268
+ **kwargs
269
+ )
270
+
271
+ @wraps(func)
272
+ def sync_wrapper(*args, **kwargs):
273
+ tracer = get_current_tracer()
274
+ if not tracer:
275
+ return func(*args, **kwargs)
276
+
277
+ # Use synchronous tool tracing
278
+ return tracer._trace_sync_custom_execution(
279
+ func,
280
+ name or func.__name__,
281
+ custom_type,
282
+ version,
283
+ trace_variables,
284
+ *args,
285
+ **kwargs
286
+ )
287
+
288
+ return async_wrapper if is_async else sync_wrapper
289
+ return decorator
290
+
291
+
292
+ def current_span():
293
+ """Get the current active span for adding metrics."""
294
+ tracer = get_current_tracer()
295
+ if not tracer:
296
+ return None
297
+
298
+ # First check for LLM context
299
+ llm_name = tracer.current_llm_call_name.get()
300
+ if llm_name:
301
+ return tracer.span(llm_name)
302
+
303
+ # Then check for tool context
304
+ tool_name = tracer.current_tool_name.get()
305
+ if tool_name:
306
+ return tracer.span(tool_name)
307
+
308
+ # Finally fall back to agent context
309
+ agent_name = tracer.current_agent_name.get()
310
+ if not agent_name:
311
+ raise ValueError("No active span found. Make sure you're calling this within a traced function.")
312
+
313
+ return tracer.span(agent_name)
@@ -98,10 +98,10 @@ class Tracer(AgenticTracing):
98
98
  "custom": False
99
99
  }
100
100
  elif isinstance(auto_instrumentation, dict):
101
- auto_instrumentation = {k: v for k, v in auto_instrumentation.items() if v}
101
+ auto_instrumentation = {k: v for k, v in auto_instrumentation.items()}
102
102
  for key in ["llm", "tool", "agent", "user_interaction", "file_io", "network", "custom"]:
103
103
  if key not in auto_instrumentation:
104
- auto_instrumentation[key] = False
104
+ auto_instrumentation[key] = True
105
105
 
106
106
  super().__init__(user_detail=user_detail, auto_instrumentation=auto_instrumentation)
107
107
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ragaai_catalyst
3
- Version: 2.1.4.1b1
3
+ Version: 2.1.5b1
4
4
  Summary: RAGA AI CATALYST
5
5
  Author-email: Kiran Scaria <kiran.scaria@raga.ai>, Kedar Gaikwad <kedar.gaikwad@raga.ai>, Dushyant Mahajan <dushyant.mahajan@raga.ai>, Siddhartha Kosti <siddhartha.kosti@raga.ai>, Ritika Goel <ritika.goel@raga.ai>, Vijay Chaurasia <vijay.chaurasia@raga.ai>
6
6
  Requires-Python: <3.13,>=3.9
@@ -34,7 +34,6 @@ Requires-Dist: psutil~=6.0.0
34
34
  Requires-Dist: py-cpuinfo~=9.0.0
35
35
  Requires-Dist: requests~=2.32.3
36
36
  Requires-Dist: GPUtil~=1.4.0
37
- Requires-Dist: astor>=0.8.1
38
37
  Requires-Dist: ipynbname
39
38
  Provides-Extra: dev
40
39
  Requires-Dist: pytest; extra == "dev"