ragaai-catalyst 2.2.2b1__py3-none-any.whl → 2.2.3b1__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.
@@ -76,14 +76,14 @@ class DynamicTraceExporter(SpanExporter):
76
76
  # Update the exporter's properties
77
77
  self._update_exporter_properties()
78
78
  except Exception as e:
79
- raise Exception(f"Error updating exporter properties: {e}")
79
+ logger.error(f"Error updating exporter properties: {e}")
80
80
 
81
81
  try:
82
82
  # Forward the call to the underlying exporter
83
83
  result = self._exporter.export(spans)
84
84
  return result
85
85
  except Exception as e:
86
- raise Exception(f"Error exporting trace: {e}")
86
+ logger.error(f"Error exporting trace: {e}")
87
87
 
88
88
 
89
89
 
@@ -96,13 +96,13 @@ class DynamicTraceExporter(SpanExporter):
96
96
  # Update the exporter's properties
97
97
  self._update_exporter_properties()
98
98
  except Exception as e:
99
- raise Exception(f"Error updating exporter properties: {e}")
99
+ logger.error(f"Error updating exporter properties: {e}")
100
100
 
101
101
  try:
102
102
  # Forward the call to the underlying exporter
103
103
  return self._exporter.shutdown()
104
104
  except Exception as e:
105
- raise Exception(f"Error shutting down exporter: {e}")
105
+ logger.error(f"Error shutting down exporter: {e}")
106
106
 
107
107
  def _update_exporter_properties(self):
108
108
  """
@@ -136,9 +136,7 @@ class FileSpanExporter(SpanExporter):
136
136
  """
137
137
  async with aiohttp.ClientSession() as session:
138
138
  if not os.getenv("RAGAAI_CATALYST_TOKEN"):
139
- raise ValueError(
140
- "RAGAAI_CATALYST_TOKEN not found. Cannot upload traces."
141
- )
139
+ logger.error("RAGAAI_CATALYST_TOKEN not found. Cannot upload traces.")
142
140
 
143
141
  try:
144
142
  upload_stat = await self.raga_client.check_and_upload_files(
@@ -60,7 +60,7 @@ class RagaExporter:
60
60
  self.secret_key = os.getenv("RAGAAI_CATALYST_SECRET_KEY")
61
61
  self.max_urls = 20
62
62
  if not self.access_key or not self.secret_key:
63
- raise ValueError(
63
+ logger.error(
64
64
  "RAGAAI_CATALYST_ACCESS_KEY and RAGAAI_CATALYST_SECRET_KEY environment variables must be set"
65
65
  )
66
66
  if not os.getenv("RAGAAI_CATALYST_TOKEN"):
@@ -68,7 +68,7 @@ class RagaExporter:
68
68
 
69
69
  create_status_code = self._create_schema()
70
70
  if create_status_code != 200:
71
- raise Exception(
71
+ logger.error(
72
72
  "Failed to create schema. Please consider raising an issue."
73
73
  )
74
74
  # elif status_code != 200:
@@ -51,7 +51,7 @@ class RAGATraceExporter(SpanExporter):
51
51
  span_json = json.loads(span.to_json())
52
52
  trace_id = span_json.get("context").get("trace_id")
53
53
  if trace_id is None:
54
- raise Exception("Trace ID is None")
54
+ logger.error("Trace ID is None")
55
55
 
56
56
  if trace_id not in self.trace_spans:
57
57
  self.trace_spans[trace_id] = list()
@@ -63,11 +63,11 @@ class RAGATraceExporter(SpanExporter):
63
63
  try:
64
64
  self.process_complete_trace(trace, trace_id)
65
65
  except Exception as e:
66
- raise Exception(f"Error processing complete trace: {e}")
66
+ logger.error(f"Error processing complete trace: {e}")
67
67
  try:
68
68
  del self.trace_spans[trace_id]
69
69
  except Exception as e:
70
- raise Exception(f"Error deleting trace: {e}")
70
+ logger.error(f"Error deleting trace: {e}")
71
71
  except Exception as e:
72
72
  logger.warning(f"Error processing span: {e}")
73
73
  continue
@@ -1,26 +1,35 @@
1
- import asyncio
1
+ import os
2
+ import uuid
2
3
  import datetime
3
- import json
4
4
  import logging
5
- import os
6
- from concurrent.futures import ThreadPoolExecutor
7
- from contextlib import contextmanager
8
- from pathlib import Path
9
-
5
+ import asyncio
10
6
  import aiohttp
11
7
  import requests
12
8
  from litellm import model_cost
9
+ from pathlib import Path
10
+ from contextlib import contextmanager
11
+ from concurrent.futures import ThreadPoolExecutor
12
+ from ragaai_catalyst.tracers.langchain_callback import LangchainTracer
13
+ from ragaai_catalyst.tracers.utils.convert_langchain_callbacks_output import convert_langchain_callbacks_output
13
14
 
14
- # from ragaai_catalyst.tracers.llamaindex_callback import LlamaIndexTracer
15
- from openinference.instrumentation.langchain import LangChainInstrumentor
15
+ from ragaai_catalyst.tracers.utils.langchain_tracer_extraction_logic import langchain_tracer_extraction
16
+ from ragaai_catalyst.tracers.upload_traces import UploadTraces
17
+ import tempfile
18
+ import json
19
+ import numpy as np
16
20
  from opentelemetry.sdk import trace as trace_sdk
17
21
  from opentelemetry.sdk.trace.export import SimpleSpanProcessor
18
-
22
+ from ragaai_catalyst.tracers.exporters.file_span_exporter import FileSpanExporter
23
+ from ragaai_catalyst.tracers.exporters.raga_exporter import RagaExporter
24
+ from ragaai_catalyst.tracers.utils import get_unique_key
25
+ # from ragaai_catalyst.tracers.llamaindex_callback import LlamaIndexTracer
26
+ from ragaai_catalyst.tracers.llamaindex_instrumentation import LlamaIndexInstrumentationTracer
27
+ from openinference.instrumentation.langchain import LangChainInstrumentor
19
28
  from ragaai_catalyst import RagaAICatalyst
20
29
  from ragaai_catalyst.tracers.agentic_tracing import AgenticTracing
30
+ from ragaai_catalyst.tracers.agentic_tracing.tracers.llm_tracer import LLMTracerMixin
31
+ from ragaai_catalyst.tracers.exporters.ragaai_trace_exporter import RAGATraceExporter
21
32
  from ragaai_catalyst.tracers.agentic_tracing.utils.file_name_tracker import TrackName
22
- from ragaai_catalyst.tracers.exporters.file_span_exporter import FileSpanExporter
23
- from ragaai_catalyst.tracers.utils import get_unique_key
24
33
 
25
34
  logger = logging.getLogger(__name__)
26
35
  logging_level = (
@@ -157,7 +166,7 @@ class Tracer(AgenticTracing):
157
166
  project["name"] for project in response.json()["data"]["content"]
158
167
  ]
159
168
  if project_name not in project_list:
160
- raise ValueError("Project not found. Please enter a valid project name")
169
+ logger.error("Project not found. Please enter a valid project name")
161
170
 
162
171
  self.project_id = [
163
172
  project["id"] for project in response.json()["data"]["content"] if project["name"] == project_name
@@ -168,7 +177,6 @@ class Tracer(AgenticTracing):
168
177
 
169
178
  except requests.exceptions.RequestException as e:
170
179
  logger.error(f"Failed to retrieve projects list: {e}")
171
- raise
172
180
 
173
181
  # if tracer_type == "langchain":
174
182
  # instrumentors = []
@@ -191,16 +199,12 @@ class Tracer(AgenticTracing):
191
199
  # Add LLM Instrumentors
192
200
  if tracer_type in ['agentic/crewai']:
193
201
  try:
194
- from openinference.instrumentation.vertexai import (
195
- VertexAIInstrumentor,
196
- )
202
+ from openinference.instrumentation.vertexai import VertexAIInstrumentor
197
203
  instrumentors.append((VertexAIInstrumentor, []))
198
204
  except (ImportError, ModuleNotFoundError):
199
205
  logger.debug("VertexAI not available in environment")
200
206
  try:
201
- from openinference.instrumentation.anthropic import (
202
- AnthropicInstrumentor,
203
- )
207
+ from openinference.instrumentation.anthropic import AnthropicInstrumentor
204
208
  instrumentors.append((AnthropicInstrumentor, []))
205
209
  except (ImportError, ModuleNotFoundError):
206
210
  logger.debug("Anthropic not available in environment")
@@ -210,16 +214,12 @@ class Tracer(AgenticTracing):
210
214
  except (ImportError, ModuleNotFoundError):
211
215
  logger.debug("Groq not available in environment")
212
216
  try:
213
- from openinference.instrumentation.litellm import (
214
- LiteLLMInstrumentor,
215
- )
217
+ from openinference.instrumentation.litellm import LiteLLMInstrumentor
216
218
  instrumentors.append((LiteLLMInstrumentor, []))
217
219
  except (ImportError, ModuleNotFoundError):
218
220
  logger.debug("LiteLLM not available in environment")
219
221
  try:
220
- from openinference.instrumentation.mistralai import (
221
- MistralAIInstrumentor,
222
- )
222
+ from openinference.instrumentation.mistralai import MistralAIInstrumentor
223
223
  instrumentors.append((MistralAIInstrumentor, []))
224
224
  except (ImportError, ModuleNotFoundError):
225
225
  logger.debug("MistralAI not available in environment")
@@ -229,9 +229,7 @@ class Tracer(AgenticTracing):
229
229
  except (ImportError, ModuleNotFoundError):
230
230
  logger.debug("OpenAI not available in environment")
231
231
  try:
232
- from openinference.instrumentation.bedrock import (
233
- BedrockInstrumentor,
234
- )
232
+ from openinference.instrumentation.bedrock import BedrockInstrumentor
235
233
  instrumentors.append((BedrockInstrumentor, []))
236
234
  except (ImportError, ModuleNotFoundError):
237
235
  logger.debug("Bedrock not available in environment")
@@ -244,9 +242,7 @@ class Tracer(AgenticTracing):
244
242
  try:
245
243
  # LlamaIndex
246
244
  try:
247
- from openinference.instrumentation.llama_index import (
248
- LlamaIndexInstrumentor,
249
- )
245
+ from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
250
246
  instrumentors.append((LlamaIndexInstrumentor, []))
251
247
  logger.info("Instrumenting LlamaIndex...")
252
248
  except (ImportError, ModuleNotFoundError):
@@ -254,9 +250,7 @@ class Tracer(AgenticTracing):
254
250
 
255
251
  # LangChain
256
252
  try:
257
- from openinference.instrumentation.langchain import (
258
- LangChainInstrumentor,
259
- )
253
+ from openinference.instrumentation.langchain import LangChainInstrumentor
260
254
  instrumentors.append((LangChainInstrumentor, []))
261
255
  logger.info("Instrumenting LangChain...")
262
256
  except (ImportError, ModuleNotFoundError):
@@ -264,9 +258,7 @@ class Tracer(AgenticTracing):
264
258
 
265
259
  # CrewAI
266
260
  try:
267
- from openinference.instrumentation.crewai import (
268
- CrewAIInstrumentor,
269
- )
261
+ from openinference.instrumentation.crewai import CrewAIInstrumentor
270
262
  instrumentors.append((CrewAIInstrumentor, []))
271
263
  logger.info("Instrumenting CrewAI...")
272
264
  except (ImportError, ModuleNotFoundError):
@@ -274,9 +266,7 @@ class Tracer(AgenticTracing):
274
266
 
275
267
  # Haystack
276
268
  try:
277
- from openinference.instrumentation.haystack import (
278
- HaystackInstrumentor,
279
- )
269
+ from openinference.instrumentation.haystack import HaystackInstrumentor
280
270
  instrumentors.append((HaystackInstrumentor, []))
281
271
  logger.info("Instrumenting Haystack...")
282
272
  except (ImportError, ModuleNotFoundError):
@@ -284,9 +274,7 @@ class Tracer(AgenticTracing):
284
274
 
285
275
  # AutoGen
286
276
  try:
287
- from openinference.instrumentation.autogen import (
288
- AutogenInstrumentor,
289
- )
277
+ from openinference.instrumentation.autogen import AutogenInstrumentor
290
278
  instrumentors.append((AutogenInstrumentor, []))
291
279
  logger.info("Instrumenting AutoGen...")
292
280
  except (ImportError, ModuleNotFoundError):
@@ -294,9 +282,7 @@ class Tracer(AgenticTracing):
294
282
 
295
283
  # Smolagents
296
284
  try:
297
- from openinference.instrumentation.smolagents import (
298
- SmolagentsInstrumentor,
299
- )
285
+ from openinference.instrumentation.smolagents import SmolagentsInstrumentor
300
286
  instrumentors.append((SmolagentsInstrumentor, []))
301
287
  logger.info("Instrumenting Smolagents...")
302
288
  except (ImportError, ModuleNotFoundError):
@@ -304,9 +290,7 @@ class Tracer(AgenticTracing):
304
290
 
305
291
  # OpenAI Agents
306
292
  try:
307
- from openinference.instrumentation.openai_agents import (
308
- OpenAIAgentsInstrumentor,
309
- )
293
+ from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
310
294
  instrumentors.append((OpenAIAgentsInstrumentor, []))
311
295
  logger.info("Instrumenting OpenAI Agents...")
312
296
  except (ImportError, ModuleNotFoundError):
@@ -324,22 +308,16 @@ class Tracer(AgenticTracing):
324
308
 
325
309
  # Handle specific framework instrumentation
326
310
  elif tracer_type == "agentic/llamaindex" or tracer_type == "llamaindex":
327
- from openinference.instrumentation.llama_index import (
328
- LlamaIndexInstrumentor,
329
- )
311
+ from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
330
312
  instrumentors += [(LlamaIndexInstrumentor, [])]
331
313
 
332
314
  elif tracer_type == "agentic/langchain" or tracer_type == "agentic/langgraph" or tracer_type == "langchain":
333
- from openinference.instrumentation.langchain import (
334
- LangChainInstrumentor,
335
- )
315
+ from openinference.instrumentation.langchain import LangChainInstrumentor
336
316
  instrumentors += [(LangChainInstrumentor, [])]
337
317
 
338
318
  elif tracer_type == "agentic/crewai":
339
319
  from openinference.instrumentation.crewai import CrewAIInstrumentor
340
- from openinference.instrumentation.langchain import (
341
- LangChainInstrumentor,
342
- )
320
+ from openinference.instrumentation.langchain import LangChainInstrumentor
343
321
  instrumentors += [(CrewAIInstrumentor, []), (LangChainInstrumentor, [])]
344
322
 
345
323
  elif tracer_type == "agentic/haystack":
@@ -351,15 +329,11 @@ class Tracer(AgenticTracing):
351
329
  instrumentors += [(AutogenInstrumentor, [])]
352
330
 
353
331
  elif tracer_type == "agentic/smolagents":
354
- from openinference.instrumentation.smolagents import (
355
- SmolagentsInstrumentor,
356
- )
332
+ from openinference.instrumentation.smolagents import SmolagentsInstrumentor
357
333
  instrumentors += [(SmolagentsInstrumentor, [])]
358
334
 
359
335
  elif tracer_type == "agentic/openai_agents":
360
- from openinference.instrumentation.openai_agents import (
361
- OpenAIAgentsInstrumentor,
362
- )
336
+ from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
363
337
  instrumentors += [(OpenAIAgentsInstrumentor, [])]
364
338
 
365
339
  else:
@@ -392,11 +366,11 @@ class Tracer(AgenticTracing):
392
366
  })
393
367
  """
394
368
  if not isinstance(cost_config, dict):
395
- raise TypeError("cost_config must be a dictionary")
369
+ logger.error("cost_config must be a dictionary")
396
370
 
397
371
  required_keys = {"model_name", "input_cost_per_million_token", "output_cost_per_million_token"}
398
372
  if not all(key in cost_config for key in required_keys):
399
- raise ValueError(f"cost_config must contain all required keys: {required_keys}")
373
+ logger.error(f"cost_config must contain all required keys: {required_keys}")
400
374
 
401
375
  model_name = cost_config["model_name"]
402
376
  self.model_custom_cost[model_name] = {
@@ -425,7 +399,7 @@ class Tracer(AgenticTracing):
425
399
  return value
426
400
  """
427
401
  if not callable(masking_func):
428
- raise TypeError("masking_func must be a callable")
402
+ logger.error("masking_func must be a callable")
429
403
 
430
404
  def recursive_mask_values(obj, parent_key=None):
431
405
  """Apply masking to all values in nested structure."""
@@ -440,7 +414,10 @@ class Tracer(AgenticTracing):
440
414
  'start_time', 'end_time', 'name', 'id',
441
415
  'hash_id', 'parent_id', 'source_hash_id',
442
416
  'cost', 'type', 'feedback', 'error', 'ctx','telemetry.sdk.version',
443
- 'telemetry.sdk.language','service.name'
417
+ 'telemetry.sdk.language','service.name', 'llm.model_name',
418
+ 'llm.invocation_parameters', 'metadata', 'openinference.span.kind',
419
+ 'llm.token_count.prompt', 'llm.token_count.completion', 'llm.token_count.total',
420
+ "input_cost", "output_cost", "total_cost", "status_code"
444
421
  }
445
422
  # Apply masking only if the key is NOT in the excluded list
446
423
  if parent_key and parent_key.lower() not in excluded_keys:
@@ -497,7 +474,7 @@ class Tracer(AgenticTracing):
497
474
  def post_processor_func(original_trace_json_path: os.PathLike) -> os.PathLike
498
475
  """
499
476
  if not callable(post_processor_func):
500
- raise TypeError("post_processor_func must be a callable")
477
+ logger.error("post_processor_func must be a callable")
501
478
  self.post_processor = post_processor_func
502
479
  # Register in parent AgenticTracing class
503
480
  super().register_post_processor(post_processor_func)
@@ -600,7 +577,7 @@ class Tracer(AgenticTracing):
600
577
  "llama_index": LlamaIndexInstrumentor,
601
578
  }
602
579
  if tracer_type not in instrumentors:
603
- raise ValueError(f"Invalid tracer type: {tracer_type}")
580
+ logger.error(f"Invalid tracer type: {tracer_type}")
604
581
  return instrumentors[tracer_type]().get()
605
582
 
606
583
  @contextmanager
@@ -721,9 +698,7 @@ class Tracer(AgenticTracing):
721
698
  """
722
699
  async with aiohttp.ClientSession() as session:
723
700
  if not os.getenv("RAGAAI_CATALYST_TOKEN"):
724
- raise ValueError(
725
- "RAGAAI_CATALYST_TOKEN not found. Cannot upload traces."
726
- )
701
+ logger.error("RAGAAI_CATALYST_TOKEN not found. Cannot upload traces.")
727
702
 
728
703
  try:
729
704
  upload_stat = await asyncio.wait_for(
@@ -807,7 +782,7 @@ class Tracer(AgenticTracing):
807
782
  AttributeError: If the tracer_type is not an agentic tracer or if the dynamic_exporter is not initialized.
808
783
  """
809
784
  if not self.tracer_type.startswith("agentic/") or not hasattr(self, "dynamic_exporter"):
810
- raise AttributeError("This method is only available for agentic tracers with a dynamic exporter.")
785
+ logger.error("This method is only available for agentic tracers with a dynamic exporter.")
811
786
 
812
787
  for key, value in kwargs.items():
813
788
  if hasattr(self.dynamic_exporter, key):
@@ -825,10 +800,7 @@ class Tracer(AgenticTracing):
825
800
  """
826
801
  from opentelemetry.sdk import trace as trace_sdk
827
802
  from opentelemetry.sdk.trace.export import SimpleSpanProcessor
828
-
829
- from ragaai_catalyst.tracers.exporters.dynamic_trace_exporter import (
830
- DynamicTraceExporter,
831
- )
803
+ from ragaai_catalyst.tracers.exporters.dynamic_trace_exporter import DynamicTraceExporter
832
804
 
833
805
  # Get the code_files
834
806
  self.file_tracker.trace_main_file()
@@ -877,7 +849,7 @@ class Tracer(AgenticTracing):
877
849
  AttributeError: If the tracer_type is not 'agentic/llamaindex' or if the dynamic_exporter is not initialized.
878
850
  """
879
851
  if not self.tracer_type.startswith("agentic/") or not hasattr(self, "dynamic_exporter"):
880
- raise AttributeError("This method is only available for agentic tracers with a dynamic exporter.")
852
+ logger.error("This method is only available for agentic tracers with a dynamic exporter.")
881
853
 
882
854
  # Get the latest list of unique files
883
855
  list_of_unique_files = self.file_tracker.get_unique_files()