ragaai-catalyst 2.1.4.1b0__py3-none-any.whl → 2.1.5__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 (64) hide show
  1. ragaai_catalyst/__init__.py +23 -2
  2. ragaai_catalyst/dataset.py +462 -1
  3. ragaai_catalyst/evaluation.py +76 -7
  4. ragaai_catalyst/ragaai_catalyst.py +52 -10
  5. ragaai_catalyst/redteaming/__init__.py +7 -0
  6. ragaai_catalyst/redteaming/config/detectors.toml +13 -0
  7. ragaai_catalyst/redteaming/data_generator/scenario_generator.py +95 -0
  8. ragaai_catalyst/redteaming/data_generator/test_case_generator.py +120 -0
  9. ragaai_catalyst/redteaming/evaluator.py +125 -0
  10. ragaai_catalyst/redteaming/llm_generator.py +136 -0
  11. ragaai_catalyst/redteaming/llm_generator_old.py +83 -0
  12. ragaai_catalyst/redteaming/red_teaming.py +331 -0
  13. ragaai_catalyst/redteaming/requirements.txt +4 -0
  14. ragaai_catalyst/redteaming/tests/grok.ipynb +97 -0
  15. ragaai_catalyst/redteaming/tests/stereotype.ipynb +2258 -0
  16. ragaai_catalyst/redteaming/upload_result.py +38 -0
  17. ragaai_catalyst/redteaming/utils/issue_description.py +114 -0
  18. ragaai_catalyst/redteaming/utils/rt.png +0 -0
  19. ragaai_catalyst/redteaming_old.py +171 -0
  20. ragaai_catalyst/synthetic_data_generation.py +400 -22
  21. ragaai_catalyst/tracers/__init__.py +17 -1
  22. ragaai_catalyst/tracers/agentic_tracing/data/data_structure.py +4 -2
  23. ragaai_catalyst/tracers/agentic_tracing/tracers/agent_tracer.py +212 -148
  24. ragaai_catalyst/tracers/agentic_tracing/tracers/base.py +657 -247
  25. ragaai_catalyst/tracers/agentic_tracing/tracers/custom_tracer.py +50 -19
  26. ragaai_catalyst/tracers/agentic_tracing/tracers/llm_tracer.py +588 -177
  27. ragaai_catalyst/tracers/agentic_tracing/tracers/main_tracer.py +99 -100
  28. ragaai_catalyst/tracers/agentic_tracing/tracers/network_tracer.py +3 -3
  29. ragaai_catalyst/tracers/agentic_tracing/tracers/tool_tracer.py +230 -29
  30. ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py +358 -0
  31. ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py +75 -20
  32. ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py +55 -11
  33. ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py +74 -0
  34. ragaai_catalyst/tracers/agentic_tracing/upload/upload_trace_metric.py +47 -16
  35. ragaai_catalyst/tracers/agentic_tracing/utils/create_dataset_schema.py +4 -2
  36. ragaai_catalyst/tracers/agentic_tracing/utils/file_name_tracker.py +26 -3
  37. ragaai_catalyst/tracers/agentic_tracing/utils/llm_utils.py +182 -17
  38. ragaai_catalyst/tracers/agentic_tracing/utils/model_costs.json +1233 -497
  39. ragaai_catalyst/tracers/agentic_tracing/utils/span_attributes.py +81 -10
  40. ragaai_catalyst/tracers/agentic_tracing/utils/supported_llm_provider.toml +34 -0
  41. ragaai_catalyst/tracers/agentic_tracing/utils/system_monitor.py +215 -0
  42. ragaai_catalyst/tracers/agentic_tracing/utils/trace_utils.py +0 -32
  43. ragaai_catalyst/tracers/agentic_tracing/utils/unique_decorator.py +3 -1
  44. ragaai_catalyst/tracers/agentic_tracing/utils/zip_list_of_unique_files.py +73 -47
  45. ragaai_catalyst/tracers/distributed.py +300 -0
  46. ragaai_catalyst/tracers/exporters/__init__.py +3 -1
  47. ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py +160 -0
  48. ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py +129 -0
  49. ragaai_catalyst/tracers/langchain_callback.py +809 -0
  50. ragaai_catalyst/tracers/llamaindex_instrumentation.py +424 -0
  51. ragaai_catalyst/tracers/tracer.py +301 -55
  52. ragaai_catalyst/tracers/upload_traces.py +24 -7
  53. ragaai_catalyst/tracers/utils/convert_langchain_callbacks_output.py +61 -0
  54. ragaai_catalyst/tracers/utils/convert_llama_instru_callback.py +69 -0
  55. ragaai_catalyst/tracers/utils/extraction_logic_llama_index.py +74 -0
  56. ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py +82 -0
  57. ragaai_catalyst/tracers/utils/model_prices_and_context_window_backup.json +9365 -0
  58. ragaai_catalyst/tracers/utils/trace_json_converter.py +269 -0
  59. {ragaai_catalyst-2.1.4.1b0.dist-info → ragaai_catalyst-2.1.5.dist-info}/METADATA +367 -45
  60. ragaai_catalyst-2.1.5.dist-info/RECORD +97 -0
  61. {ragaai_catalyst-2.1.4.1b0.dist-info → ragaai_catalyst-2.1.5.dist-info}/WHEEL +1 -1
  62. ragaai_catalyst-2.1.4.1b0.dist-info/RECORD +0 -67
  63. {ragaai_catalyst-2.1.4.1b0.dist-info → ragaai_catalyst-2.1.5.dist-info}/LICENSE +0 -0
  64. {ragaai_catalyst-2.1.4.1b0.dist-info → ragaai_catalyst-2.1.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,300 @@
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 .agentic_tracing.utils.unique_decorator import generate_unique_hash_simple
13
+ from datetime import datetime
14
+ import asyncio
15
+
16
+ from .tracer import Tracer
17
+ from ..ragaai_catalyst import RagaAICatalyst
18
+
19
+ # Global state
20
+ _global_tracer: Optional[Tracer] = None
21
+ _global_catalyst: Optional[RagaAICatalyst] = None
22
+ _tracer_lock = threading.Lock()
23
+ _active_spans = threading.local()
24
+
25
+ def get_current_tracer() -> Optional[Tracer]:
26
+ """Get the current global tracer instance."""
27
+ return _global_tracer
28
+
29
+ def get_current_catalyst() -> Optional[RagaAICatalyst]:
30
+ """Get the current global catalyst instance."""
31
+ return _global_catalyst
32
+
33
+ def init_tracing(
34
+ project_name: str = None,
35
+ dataset_name: str = None,
36
+ access_key: str = None,
37
+ secret_key: str = None,
38
+ base_url: str = None,
39
+ tracer: Tracer = None,
40
+ catalyst: RagaAICatalyst = None,
41
+ **kwargs
42
+ ) -> None:
43
+ """Initialize distributed tracing.
44
+
45
+ Args:
46
+ project_name: Project name for new tracer
47
+ dataset_name: Dataset name for new tracer
48
+ access_key: RagaAI Catalyst access key
49
+ secret_key: RagaAI Catalyst secret key
50
+ base_url: RagaAI Catalyst API base URL
51
+ tracer: Existing Tracer instance
52
+ catalyst: Existing RagaAICatalyst instance
53
+ **kwargs: Additional tracer parameters
54
+ """
55
+ global _global_tracer, _global_catalyst
56
+
57
+ with _tracer_lock:
58
+ if tracer and catalyst:
59
+ if isinstance(tracer, Tracer) and isinstance(catalyst, RagaAICatalyst):
60
+ _global_tracer = tracer
61
+ _global_catalyst = catalyst
62
+ else:
63
+ raise ValueError("Both Tracer and Catalyst objects must be instances of Tracer and RagaAICatalyst, respectively.")
64
+ else:
65
+ raise ValueError("Both Tracer and Catalyst objects must be provided.")
66
+
67
+
68
+ def trace_agent(name: str = None, agent_type: str = "generic", version: str = "1.0.0", **kwargs):
69
+ """Decorator for tracing agent functions."""
70
+ def decorator(func):
71
+ is_async = asyncio.iscoroutinefunction(func)
72
+ span_name = name or func.__name__
73
+ # Generate hash based on the decorated function
74
+ top_level_hash_id = generate_unique_hash_simple(func)
75
+
76
+ @wraps(func)
77
+ async def async_wrapper(*args, **kwargs):
78
+ tracer = get_current_tracer()
79
+ if not tracer:
80
+ return await func(*args, **kwargs)
81
+
82
+ # Set current agent name and store the token
83
+ name_token = tracer.current_agent_name.set(span_name)
84
+
85
+ try:
86
+ # Use async agent tracing
87
+ return await tracer._trace_agent_execution(
88
+ func,
89
+ span_name,
90
+ agent_type,
91
+ version,
92
+ None, # capabilities
93
+ top_level_hash_id,
94
+ *args,
95
+ **kwargs
96
+ )
97
+ finally:
98
+ # Reset using the stored token
99
+ if name_token:
100
+ tracer.current_agent_name.reset(name_token)
101
+
102
+ @wraps(func)
103
+ def sync_wrapper(*args, **kwargs):
104
+ tracer = get_current_tracer()
105
+ if not tracer:
106
+ return func(*args, **kwargs)
107
+
108
+ # Set current agent name and store the token
109
+ name_token = tracer.current_agent_name.set(span_name)
110
+
111
+ try:
112
+ # Use synchronous agent tracing
113
+ return tracer._trace_sync_agent_execution(
114
+ func,
115
+ span_name,
116
+ agent_type,
117
+ version,
118
+ None, # capabilities
119
+ top_level_hash_id,
120
+ *args,
121
+ **kwargs
122
+ )
123
+ finally:
124
+ # Reset using the stored token
125
+ if name_token:
126
+ tracer.current_agent_name.reset(name_token)
127
+
128
+ return async_wrapper if is_async else sync_wrapper
129
+ return decorator
130
+
131
+ def trace_llm(name: str = None, model: str = None, **kwargs):
132
+ """Decorator for tracing LLM calls."""
133
+ def decorator(func):
134
+ is_async = asyncio.iscoroutinefunction(func)
135
+ span_name = name or func.__name__
136
+
137
+ @wraps(func)
138
+ async def async_wrapper(*args, **kwargs):
139
+ tracer = get_current_tracer()
140
+ if not tracer:
141
+ return await func(*args, **kwargs)
142
+
143
+ # Set current LLM name and store the token
144
+ name_token = tracer.current_llm_call_name.set(span_name)
145
+
146
+ try:
147
+ # Just execute the function within the current span
148
+ result = await func(*args, **kwargs)
149
+ return result
150
+ finally:
151
+ # Reset using the stored token
152
+ if name_token:
153
+ tracer.current_llm_call_name.reset(name_token)
154
+
155
+ @wraps(func)
156
+ def sync_wrapper(*args, **kwargs):
157
+ tracer = get_current_tracer()
158
+ if not tracer:
159
+ return func(*args, **kwargs)
160
+
161
+ # Set current LLM name and store the token
162
+ name_token = tracer.current_llm_call_name.set(span_name)
163
+
164
+ try:
165
+ # Just execute the function within the current span
166
+ result = func(*args, **kwargs)
167
+ return result
168
+ finally:
169
+ # Reset using the stored token
170
+ if name_token:
171
+ tracer.current_llm_call_name.reset(name_token)
172
+
173
+ return async_wrapper if is_async else sync_wrapper
174
+ return decorator
175
+
176
+
177
+ def trace_tool(name: str = None, tool_type: str = "generic", version: str = "1.0.0", **kwargs):
178
+ """Decorator for tracing tool functions."""
179
+ def decorator(func):
180
+ is_async = asyncio.iscoroutinefunction(func)
181
+ span_name = name or func.__name__
182
+
183
+ @wraps(func)
184
+ async def async_wrapper(*args, **kwargs):
185
+ tracer = get_current_tracer()
186
+ if not tracer:
187
+ return await func(*args, **kwargs)
188
+
189
+ # Set current tool name and store the token
190
+ name_token = tracer.current_tool_name.set(span_name)
191
+
192
+ try:
193
+ # Use async tool tracing
194
+ return await tracer._trace_tool_execution(
195
+ func,
196
+ span_name,
197
+ tool_type,
198
+ version,
199
+ *args,
200
+ **kwargs
201
+ )
202
+ finally:
203
+ # Reset using the stored token
204
+ if name_token:
205
+ tracer.current_tool_name.reset(name_token)
206
+
207
+ @wraps(func)
208
+ def sync_wrapper(*args, **kwargs):
209
+ tracer = get_current_tracer()
210
+ if not tracer:
211
+ return func(*args, **kwargs)
212
+
213
+ # Set current tool name and store the token
214
+ name_token = tracer.current_tool_name.set(span_name)
215
+
216
+ try:
217
+ # Use synchronous tool tracing
218
+ return tracer._trace_sync_tool_execution(
219
+ func,
220
+ span_name,
221
+ tool_type,
222
+ version,
223
+ *args,
224
+ **kwargs
225
+ )
226
+ finally:
227
+ # Reset using the stored token
228
+ if name_token:
229
+ tracer.current_tool_name.reset(name_token)
230
+
231
+ return async_wrapper if is_async else sync_wrapper
232
+ return decorator
233
+
234
+
235
+
236
+ def trace_custom(name: str = None, custom_type: str = "generic", version: str = "1.0.0", trace_variables: bool = False, **kwargs):
237
+ """Decorator for tracing custom functions."""
238
+ def decorator(func):
239
+ is_async = asyncio.iscoroutinefunction(func)
240
+
241
+ @wraps(func)
242
+ async def async_wrapper(*args, **kwargs):
243
+ tracer = get_current_tracer()
244
+ if not tracer:
245
+ return await func(*args, **kwargs)
246
+
247
+ # Use async tool tracing
248
+ return await tracer._trace_custom_execution(
249
+ func,
250
+ name or func.__name__,
251
+ custom_type,
252
+ version,
253
+ trace_variables,
254
+ *args,
255
+ **kwargs
256
+ )
257
+
258
+ @wraps(func)
259
+ def sync_wrapper(*args, **kwargs):
260
+ tracer = get_current_tracer()
261
+ if not tracer:
262
+ return func(*args, **kwargs)
263
+
264
+ # Use synchronous tool tracing
265
+ return tracer._trace_sync_custom_execution(
266
+ func,
267
+ name or func.__name__,
268
+ custom_type,
269
+ version,
270
+ trace_variables,
271
+ *args,
272
+ **kwargs
273
+ )
274
+
275
+ return async_wrapper if is_async else sync_wrapper
276
+ return decorator
277
+
278
+
279
+ def current_span():
280
+ """Get the current active span for adding metrics."""
281
+ tracer = get_current_tracer()
282
+ if not tracer:
283
+ return None
284
+
285
+ # First check for LLM context
286
+ llm_name = tracer.current_llm_call_name.get()
287
+ if llm_name:
288
+ return tracer.span(llm_name)
289
+
290
+ # Then check for tool context
291
+ tool_name = tracer.current_tool_name.get()
292
+ if tool_name:
293
+ return tracer.span(tool_name)
294
+
295
+ # Finally fall back to agent context
296
+ agent_name = tracer.current_agent_name.get()
297
+ if not agent_name:
298
+ raise ValueError("No active span found. Make sure you're calling this within a traced function.")
299
+
300
+ return tracer.span(agent_name)
@@ -1,5 +1,7 @@
1
1
  from .file_span_exporter import FileSpanExporter
2
2
  from .raga_exporter import RagaExporter
3
+ from .ragaai_trace_exporter import RAGATraceExporter
4
+ from .dynamic_trace_exporter import DynamicTraceExporter
3
5
 
4
6
 
5
- __all__ = ["FileSpanExporter", "RagaExporter"]
7
+ __all__ = ["FileSpanExporter", "RagaExporter", "RAGATraceExporter", "DynamicTraceExporter"]
@@ -0,0 +1,160 @@
1
+ """
2
+ Dynamic Trace Exporter - A wrapper for RAGATraceExporter that allows dynamic updates to properties.
3
+ """
4
+ import logging
5
+ from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
6
+ from ragaai_catalyst.tracers.exporters.ragaai_trace_exporter import RAGATraceExporter
7
+
8
+ logger = logging.getLogger("RagaAICatalyst")
9
+
10
+ class DynamicTraceExporter(SpanExporter):
11
+ """
12
+ A wrapper around RAGATraceExporter that allows dynamic updates to properties.
13
+ This exporter forwards all calls to the underlying RAGATraceExporter but allows
14
+ certain properties to be updated dynamically during execution.
15
+ """
16
+
17
+ def __init__(self, files_to_zip, project_name, project_id, dataset_name, user_details, base_url, custom_model_cost):
18
+ """
19
+ Initialize the DynamicTraceExporter.
20
+
21
+ Args:
22
+ files_to_zip: List of files to zip
23
+ project_name: Project name
24
+ project_id: Project ID
25
+ dataset_name: Dataset name
26
+ user_details: User details
27
+ base_url: Base URL for API
28
+ """
29
+ self._exporter = RAGATraceExporter(
30
+ files_to_zip=files_to_zip,
31
+ project_name=project_name,
32
+ project_id=project_id,
33
+ dataset_name=dataset_name,
34
+ user_details=user_details,
35
+ base_url=base_url,
36
+ custom_model_cost=custom_model_cost
37
+ )
38
+
39
+ # Store the initial values
40
+ self._files_to_zip = files_to_zip
41
+ self._project_name = project_name
42
+ self._project_id = project_id
43
+ self._dataset_name = dataset_name
44
+ self._user_details = user_details
45
+ self._base_url = base_url
46
+ self._custom_model_cost = custom_model_cost
47
+
48
+
49
+ def export(self, spans):
50
+ """
51
+ Export spans by forwarding to the underlying exporter.
52
+ Before exporting, update the exporter's properties with the current values.
53
+
54
+ Args:
55
+ spans: Spans to export
56
+
57
+ Returns:
58
+ SpanExportResult: Result of the export operation
59
+ """
60
+ try:
61
+ # Update the exporter's properties
62
+ self._update_exporter_properties()
63
+ except Exception as e:
64
+ raise Exception(f"Error updating exporter properties: {e}")
65
+
66
+ try:
67
+ # Forward the call to the underlying exporter
68
+ result = self._exporter.export(spans)
69
+ return result
70
+ except Exception as e:
71
+ raise Exception(f"Error exporting trace: {e}")
72
+
73
+
74
+
75
+ def shutdown(self):
76
+ """
77
+ Shutdown the exporter by forwarding to the underlying exporter.
78
+ Before shutting down, update the exporter's properties with the current values.
79
+ """
80
+ try:
81
+ # Update the exporter's properties
82
+ self._update_exporter_properties()
83
+ except Exception as e:
84
+ raise Exception(f"Error updating exporter properties: {e}")
85
+
86
+ try:
87
+ # Forward the call to the underlying exporter
88
+ return self._exporter.shutdown()
89
+ except Exception as e:
90
+ raise Exception(f"Error shutting down exporter: {e}")
91
+
92
+ def _update_exporter_properties(self):
93
+ """
94
+ Update the underlying exporter's properties with the current values.
95
+ """
96
+ self._exporter.files_to_zip = self._files_to_zip
97
+ self._exporter.project_name = self._project_name
98
+ self._exporter.project_id = self._project_id
99
+ self._exporter.dataset_name = self._dataset_name
100
+ self._exporter.user_details = self._user_details
101
+ self._exporter.base_url = self._base_url
102
+ self._exporter.custom_model_cost = self._custom_model_cost
103
+
104
+ # Getter and setter methods for dynamic properties
105
+
106
+ @property
107
+ def files_to_zip(self):
108
+ return self._files_to_zip
109
+
110
+ @files_to_zip.setter
111
+ def files_to_zip(self, value):
112
+ self._files_to_zip = value
113
+
114
+ @property
115
+ def project_name(self):
116
+ return self._project_name
117
+
118
+ @project_name.setter
119
+ def project_name(self, value):
120
+ self._project_name = value
121
+
122
+ @property
123
+ def project_id(self):
124
+ return self._project_id
125
+
126
+ @project_id.setter
127
+ def project_id(self, value):
128
+ self._project_id = value
129
+
130
+ @property
131
+ def dataset_name(self):
132
+ return self._dataset_name
133
+
134
+ @dataset_name.setter
135
+ def dataset_name(self, value):
136
+ self._dataset_name = value
137
+
138
+ @property
139
+ def user_details(self):
140
+ return self._user_details
141
+
142
+ @user_details.setter
143
+ def user_details(self, value):
144
+ self._user_details = value
145
+
146
+ @property
147
+ def base_url(self):
148
+ return self._base_url
149
+
150
+ @base_url.setter
151
+ def base_url(self, value):
152
+ self._base_url = value
153
+
154
+ @property
155
+ def custom_model_cost(self):
156
+ return self._custom_model_cost
157
+
158
+ @custom_model_cost.setter
159
+ def custom_model_cost(self, value):
160
+ self._custom_model_cost = value
@@ -0,0 +1,129 @@
1
+ import os
2
+ import json
3
+ import tempfile
4
+ from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
5
+ import logging
6
+ from datetime import datetime
7
+ from dataclasses import asdict
8
+ from ragaai_catalyst.tracers.utils.trace_json_converter import convert_json_format
9
+ from ragaai_catalyst.tracers.agentic_tracing.tracers.base import TracerJSONEncoder
10
+ from ragaai_catalyst.tracers.agentic_tracing.utils.system_monitor import SystemMonitor
11
+ from ragaai_catalyst.tracers.agentic_tracing.upload.trace_uploader import submit_upload_task
12
+ from ragaai_catalyst.tracers.agentic_tracing.utils.zip_list_of_unique_files import zip_list_of_unique_files
13
+
14
+
15
+ logger = logging.getLogger("RagaAICatalyst")
16
+ logging_level = (
17
+ logger.setLevel(logging.DEBUG) if os.getenv("DEBUG") == "1" else logging.INFO
18
+ )
19
+
20
+
21
+ class RAGATraceExporter(SpanExporter):
22
+ def __init__(self, files_to_zip, project_name, project_id, dataset_name, user_details, base_url, custom_model_cost):
23
+ self.trace_spans = dict()
24
+ self.tmp_dir = tempfile.gettempdir()
25
+ self.files_to_zip = files_to_zip
26
+ self.project_name = project_name
27
+ self.project_id = project_id
28
+ self.dataset_name = dataset_name
29
+ self.user_details = user_details
30
+ self.base_url = base_url
31
+ self.custom_model_cost = custom_model_cost
32
+ self.system_monitor = SystemMonitor(dataset_name)
33
+
34
+ def export(self, spans):
35
+ for span in spans:
36
+ span_json = json.loads(span.to_json())
37
+ trace_id = span_json.get("context").get("trace_id")
38
+ if trace_id is None:
39
+ raise Exception("Trace ID is None")
40
+
41
+ if trace_id not in self.trace_spans:
42
+ self.trace_spans[trace_id] = list()
43
+
44
+ self.trace_spans[trace_id].append(span_json)
45
+
46
+ if span_json["parent_id"] is None:
47
+ trace = self.trace_spans[trace_id]
48
+ try:
49
+ self.process_complete_trace(trace, trace_id)
50
+ except Exception as e:
51
+ raise Exception(f"Error processing complete trace: {e}")
52
+ try:
53
+ del self.trace_spans[trace_id]
54
+ except Exception as e:
55
+ raise Exception(f"Error deleting trace: {e}")
56
+
57
+ return SpanExportResult.SUCCESS
58
+
59
+ def shutdown(self):
60
+ # Process any remaining traces during shutdown
61
+ for trace_id, spans in self.trace_spans.items():
62
+ self.process_complete_trace(spans, trace_id)
63
+ self.trace_spans.clear()
64
+
65
+ def process_complete_trace(self, spans, trace_id):
66
+ # Convert the trace to ragaai trace format
67
+ try:
68
+ ragaai_trace_details = self.prepare_trace(spans, trace_id)
69
+ except Exception as e:
70
+ print(f"Error converting trace {trace_id}: {e}")
71
+
72
+ # Upload the trace if upload_trace function is provided
73
+ try:
74
+ self.upload_trace(ragaai_trace_details, trace_id)
75
+ except Exception as e:
76
+ print(f"Error uploading trace {trace_id}: {e}")
77
+
78
+ def prepare_trace(self, spans, trace_id):
79
+ try:
80
+ ragaai_trace = convert_json_format(spans, self.custom_model_cost)
81
+ ragaai_trace["workflow"] = []
82
+
83
+ # Add source code hash
84
+ hash_id, zip_path = zip_list_of_unique_files(
85
+ self.files_to_zip, output_dir=self.tmp_dir
86
+ )
87
+
88
+ ragaai_trace["metadata"]["system_info"] = asdict(self.system_monitor.get_system_info())
89
+ ragaai_trace["metadata"]["resources"] = asdict(self.system_monitor.get_resources())
90
+ ragaai_trace["metadata"]["system_info"]["source_code"] = hash_id
91
+
92
+ ragaai_trace["data"][0]["start_time"] = ragaai_trace["start_time"]
93
+ ragaai_trace["data"][0]["end_time"] = ragaai_trace["end_time"]
94
+
95
+ ragaai_trace["project_name"] = self.project_name
96
+
97
+ # Save the trace_json
98
+ trace_file_path = os.path.join(self.tmp_dir, f"{trace_id}.json")
99
+ with open(trace_file_path, "w") as file:
100
+ json.dump(ragaai_trace, file, cls=TracerJSONEncoder, indent=2)
101
+
102
+ return {
103
+ 'trace_file_path': trace_file_path,
104
+ 'code_zip_path': zip_path,
105
+ 'hash_id': hash_id
106
+ }
107
+ except Exception as e:
108
+ logger.error(f"Error converting trace {trace_id}: {str(e)}")
109
+ return None
110
+
111
+ def upload_trace(self, ragaai_trace_details, trace_id):
112
+ filepath = ragaai_trace_details['trace_file_path']
113
+ hash_id = ragaai_trace_details['hash_id']
114
+ zip_path = ragaai_trace_details['code_zip_path']
115
+
116
+
117
+
118
+ self.upload_task_id = submit_upload_task(
119
+ filepath=filepath,
120
+ hash_id=hash_id,
121
+ zip_path=zip_path,
122
+ project_name=self.project_name,
123
+ project_id=self.project_id,
124
+ dataset_name=self.dataset_name,
125
+ user_details=self.user_details,
126
+ base_url=self.base_url
127
+ )
128
+
129
+ logger.info(f"Submitted upload task with ID: {self.upload_task_id}")