ragaai-catalyst 2.1.5b36__py3-none-any.whl → 2.1.5b37__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.
- ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py +4 -1
- ragaai_catalyst/tracers/exporters/__init__.py +3 -1
- ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py +145 -0
- ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py +121 -0
- ragaai_catalyst/tracers/tracer.py +117 -23
- ragaai_catalyst/tracers/utils/trace_json_converter.py +266 -0
- {ragaai_catalyst-2.1.5b36.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/METADATA +5 -1
- {ragaai_catalyst-2.1.5b36.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/RECORD +11 -8
- {ragaai_catalyst-2.1.5b36.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/LICENSE +0 -0
- {ragaai_catalyst-2.1.5b36.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/WHEEL +0 -0
- {ragaai_catalyst-2.1.5b36.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/top_level.txt +0 -0
@@ -95,6 +95,9 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
|
95
95
|
Returns:
|
96
96
|
Dict containing status and any error information
|
97
97
|
"""
|
98
|
+
# Correct base_url
|
99
|
+
base_url = base_url[0] if isinstance(base_url, tuple) else base_url
|
100
|
+
|
98
101
|
logger.info(f"Processing upload task {task_id}")
|
99
102
|
result = {
|
100
103
|
"task_id": task_id,
|
@@ -118,7 +121,7 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
|
118
121
|
|
119
122
|
if not IMPORTS_AVAILABLE:
|
120
123
|
logger.warning(f"Test mode: Simulating processing of task {task_id}")
|
121
|
-
time.sleep(2) # Simulate work
|
124
|
+
# time.sleep(2) # Simulate work
|
122
125
|
result["status"] = STATUS_COMPLETED
|
123
126
|
save_task_status(result)
|
124
127
|
return result
|
@@ -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,145 @@
|
|
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
|
+
# Update the exporter's properties
|
61
|
+
self._update_exporter_properties()
|
62
|
+
|
63
|
+
# Forward the call to the underlying exporter
|
64
|
+
return self._exporter.export(spans)
|
65
|
+
|
66
|
+
def shutdown(self):
|
67
|
+
"""
|
68
|
+
Shutdown the exporter by forwarding to the underlying exporter.
|
69
|
+
Before shutting down, update the exporter's properties with the current values.
|
70
|
+
"""
|
71
|
+
# Update the exporter's properties
|
72
|
+
self._update_exporter_properties()
|
73
|
+
|
74
|
+
# Forward the call to the underlying exporter
|
75
|
+
return self._exporter.shutdown()
|
76
|
+
|
77
|
+
def _update_exporter_properties(self):
|
78
|
+
"""
|
79
|
+
Update the underlying exporter's properties with the current values.
|
80
|
+
"""
|
81
|
+
self._exporter.files_to_zip = self._files_to_zip
|
82
|
+
self._exporter.project_name = self._project_name
|
83
|
+
self._exporter.project_id = self._project_id
|
84
|
+
self._exporter.dataset_name = self._dataset_name
|
85
|
+
self._exporter.user_details = self._user_details
|
86
|
+
self._exporter.base_url = self._base_url
|
87
|
+
self._exporter.custom_model_cost = self._custom_model_cost
|
88
|
+
|
89
|
+
# Getter and setter methods for dynamic properties
|
90
|
+
|
91
|
+
@property
|
92
|
+
def files_to_zip(self):
|
93
|
+
return self._files_to_zip
|
94
|
+
|
95
|
+
@files_to_zip.setter
|
96
|
+
def files_to_zip(self, value):
|
97
|
+
self._files_to_zip = value
|
98
|
+
|
99
|
+
@property
|
100
|
+
def project_name(self):
|
101
|
+
return self._project_name
|
102
|
+
|
103
|
+
@project_name.setter
|
104
|
+
def project_name(self, value):
|
105
|
+
self._project_name = value
|
106
|
+
|
107
|
+
@property
|
108
|
+
def project_id(self):
|
109
|
+
return self._project_id
|
110
|
+
|
111
|
+
@project_id.setter
|
112
|
+
def project_id(self, value):
|
113
|
+
self._project_id = value
|
114
|
+
|
115
|
+
@property
|
116
|
+
def dataset_name(self):
|
117
|
+
return self._dataset_name
|
118
|
+
|
119
|
+
@dataset_name.setter
|
120
|
+
def dataset_name(self, value):
|
121
|
+
self._dataset_name = value
|
122
|
+
|
123
|
+
@property
|
124
|
+
def user_details(self):
|
125
|
+
return self._user_details
|
126
|
+
|
127
|
+
@user_details.setter
|
128
|
+
def user_details(self, value):
|
129
|
+
self._user_details = value
|
130
|
+
|
131
|
+
@property
|
132
|
+
def base_url(self):
|
133
|
+
return self._base_url
|
134
|
+
|
135
|
+
@base_url.setter
|
136
|
+
def base_url(self, value):
|
137
|
+
self._base_url = value
|
138
|
+
|
139
|
+
@property
|
140
|
+
def custom_model_cost(self):
|
141
|
+
return self._custom_model_cost
|
142
|
+
|
143
|
+
@custom_model_cost.setter
|
144
|
+
def custom_model_cost(self, value):
|
145
|
+
self._custom_model_cost = value
|
@@ -0,0 +1,121 @@
|
|
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
|
+
|
39
|
+
if trace_id not in self.trace_spans:
|
40
|
+
self.trace_spans[trace_id] = list()
|
41
|
+
|
42
|
+
self.trace_spans[trace_id].append(span_json)
|
43
|
+
|
44
|
+
if span_json["parent_id"] is None:
|
45
|
+
trace = self.trace_spans[trace_id]
|
46
|
+
self.process_complete_trace(trace, trace_id)
|
47
|
+
del self.trace_spans[trace_id]
|
48
|
+
|
49
|
+
return SpanExportResult.SUCCESS
|
50
|
+
|
51
|
+
def shutdown(self):
|
52
|
+
# Process any remaining traces during shutdown
|
53
|
+
for trace_id, spans in self.trace_spans.items():
|
54
|
+
self.process_complete_trace(spans, trace_id)
|
55
|
+
self.trace_spans.clear()
|
56
|
+
|
57
|
+
def process_complete_trace(self, spans, trace_id):
|
58
|
+
# Convert the trace to ragaai trace format
|
59
|
+
try:
|
60
|
+
ragaai_trace_details = self.prepare_trace(spans, trace_id)
|
61
|
+
except Exception as e:
|
62
|
+
print(f"Error converting trace {trace_id}: {e}")
|
63
|
+
|
64
|
+
# Upload the trace if upload_trace function is provided
|
65
|
+
try:
|
66
|
+
self.upload_trace(ragaai_trace_details, trace_id)
|
67
|
+
except Exception as e:
|
68
|
+
print(f"Error uploading trace {trace_id}: {e}")
|
69
|
+
|
70
|
+
def prepare_trace(self, spans, trace_id):
|
71
|
+
try:
|
72
|
+
ragaai_trace = convert_json_format(spans, self.custom_model_cost)
|
73
|
+
ragaai_trace["workflow"] = []
|
74
|
+
|
75
|
+
# Add source code hash
|
76
|
+
hash_id, zip_path = zip_list_of_unique_files(
|
77
|
+
self.files_to_zip, output_dir=self.tmp_dir
|
78
|
+
)
|
79
|
+
|
80
|
+
ragaai_trace["metadata"]["system_info"] = asdict(self.system_monitor.get_system_info())
|
81
|
+
ragaai_trace["metadata"]["resources"] = asdict(self.system_monitor.get_resources())
|
82
|
+
ragaai_trace["metadata"]["system_info"]["source_code"] = hash_id
|
83
|
+
|
84
|
+
ragaai_trace["data"][0]["start_time"] = ragaai_trace["start_time"]
|
85
|
+
ragaai_trace["data"][0]["end_time"] = ragaai_trace["end_time"]
|
86
|
+
|
87
|
+
ragaai_trace["project_name"] = self.project_name
|
88
|
+
|
89
|
+
# Save the trace_json
|
90
|
+
trace_file_path = os.path.join(self.tmp_dir, f"{trace_id}.json")
|
91
|
+
with open(trace_file_path, "w") as file:
|
92
|
+
json.dump(ragaai_trace, file, cls=TracerJSONEncoder, indent=2)
|
93
|
+
|
94
|
+
return {
|
95
|
+
'trace_file_path': trace_file_path,
|
96
|
+
'code_zip_path': zip_path,
|
97
|
+
'hash_id': hash_id
|
98
|
+
}
|
99
|
+
except Exception as e:
|
100
|
+
logger.error(f"Error converting trace {trace_id}: {str(e)}")
|
101
|
+
return None
|
102
|
+
|
103
|
+
def upload_trace(self, ragaai_trace_details, trace_id):
|
104
|
+
filepath = ragaai_trace_details['trace_file_path']
|
105
|
+
hash_id = ragaai_trace_details['hash_id']
|
106
|
+
zip_path = ragaai_trace_details['code_zip_path']
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
self.upload_task_id = submit_upload_task(
|
111
|
+
filepath=filepath,
|
112
|
+
hash_id=hash_id,
|
113
|
+
zip_path=zip_path,
|
114
|
+
project_name=self.project_name,
|
115
|
+
project_id=self.project_id,
|
116
|
+
dataset_name=self.dataset_name,
|
117
|
+
user_details=self.user_details,
|
118
|
+
base_url=self.base_url
|
119
|
+
)
|
120
|
+
|
121
|
+
logger.info(f"Submitted upload task with ID: {self.upload_task_id}")
|
@@ -31,13 +31,15 @@ from ragaai_catalyst.tracers.utils import get_unique_key
|
|
31
31
|
# from ragaai_catalyst.tracers.llamaindex_callback import LlamaIndexTracer
|
32
32
|
from ragaai_catalyst.tracers.llamaindex_instrumentation import LlamaIndexInstrumentationTracer
|
33
33
|
from ragaai_catalyst import RagaAICatalyst
|
34
|
-
from ragaai_catalyst.tracers.agentic_tracing import AgenticTracing
|
34
|
+
from ragaai_catalyst.tracers.agentic_tracing import AgenticTracing
|
35
35
|
from ragaai_catalyst.tracers.agentic_tracing.tracers.llm_tracer import LLMTracerMixin
|
36
|
+
from ragaai_catalyst.tracers.exporters.ragaai_trace_exporter import RAGATraceExporter
|
37
|
+
from ragaai_catalyst.tracers.agentic_tracing.utils.file_name_tracker import TrackName
|
36
38
|
|
37
39
|
logger = logging.getLogger(__name__)
|
38
40
|
|
39
41
|
class Tracer(AgenticTracing):
|
40
|
-
NUM_PROJECTS =
|
42
|
+
NUM_PROJECTS = 99999
|
41
43
|
TIMEOUT = 10
|
42
44
|
def __init__(
|
43
45
|
self,
|
@@ -88,7 +90,17 @@ class Tracer(AgenticTracing):
|
|
88
90
|
|
89
91
|
# take care of auto_instrumentation
|
90
92
|
if isinstance(auto_instrumentation, bool):
|
91
|
-
if
|
93
|
+
if tracer_type == "agentic/llamaindex":
|
94
|
+
auto_instrumentation = {
|
95
|
+
"llm": False,
|
96
|
+
"tool": False,
|
97
|
+
"agent": False,
|
98
|
+
"user_interaction": False,
|
99
|
+
"file_io": False,
|
100
|
+
"network": False,
|
101
|
+
"custom": False
|
102
|
+
}
|
103
|
+
elif auto_instrumentation:
|
92
104
|
auto_instrumentation = {
|
93
105
|
"llm": True,
|
94
106
|
"tool": True,
|
@@ -127,10 +139,11 @@ class Tracer(AgenticTracing):
|
|
127
139
|
self.upload_timeout = upload_timeout
|
128
140
|
self.base_url = f"{RagaAICatalyst.BASE_URL}"
|
129
141
|
self.timeout = 30
|
130
|
-
self.num_projects =
|
142
|
+
self.num_projects = 99999
|
131
143
|
self.start_time = datetime.datetime.now().astimezone().isoformat()
|
132
144
|
self.model_cost_dict = model_cost
|
133
145
|
self.user_context = "" # Initialize user_context to store context from add_context
|
146
|
+
self.file_tracker = TrackName()
|
134
147
|
|
135
148
|
try:
|
136
149
|
response = requests.get(
|
@@ -171,7 +184,30 @@ class Tracer(AgenticTracing):
|
|
171
184
|
elif tracer_type == "llamaindex":
|
172
185
|
self._upload_task = None
|
173
186
|
self.llamaindex_tracer = None
|
174
|
-
|
187
|
+
elif tracer_type == "agentic/llamaindex":
|
188
|
+
from opentelemetry.sdk import trace as trace_sdk
|
189
|
+
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
|
190
|
+
from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
|
191
|
+
from ragaai_catalyst.tracers.exporters.dynamic_trace_exporter import DynamicTraceExporter
|
192
|
+
|
193
|
+
# Get the code_files
|
194
|
+
self.file_tracker.trace_main_file()
|
195
|
+
list_of_unique_files = self.file_tracker.get_unique_files()
|
196
|
+
|
197
|
+
# Create a dynamic exporter that allows property updates
|
198
|
+
self.dynamic_exporter = DynamicTraceExporter(
|
199
|
+
files_to_zip=list_of_unique_files,
|
200
|
+
project_name=self.project_name,
|
201
|
+
project_id=self.project_id,
|
202
|
+
dataset_name=self.dataset_name,
|
203
|
+
user_details=self.user_details,
|
204
|
+
base_url=self.base_url,
|
205
|
+
custom_model_cost=self.model_custom_cost
|
206
|
+
)
|
207
|
+
|
208
|
+
tracer_provider = trace_sdk.TracerProvider()
|
209
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(self.dynamic_exporter))
|
210
|
+
LlamaIndexInstrumentor().instrument(tracer_provider=tracer_provider)
|
175
211
|
else:
|
176
212
|
self._upload_task = None
|
177
213
|
# raise ValueError (f"Currently supported tracer types are 'langchain' and 'llamaindex'.")
|
@@ -206,30 +242,44 @@ class Tracer(AgenticTracing):
|
|
206
242
|
"output_cost_per_token": float(cost_config["output_cost_per_million_token"]) /1000000
|
207
243
|
}
|
208
244
|
|
209
|
-
|
210
|
-
|
211
245
|
def set_dataset_name(self, dataset_name):
|
212
246
|
"""
|
213
247
|
Reinitialize the Tracer with a new dataset name while keeping all other parameters the same.
|
248
|
+
If using agentic/llamaindex tracer with dynamic exporter, update the exporter's dataset_name property.
|
214
249
|
|
215
250
|
Args:
|
216
251
|
dataset_name (str): The new dataset name to set
|
217
252
|
"""
|
218
|
-
#
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
'
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
253
|
+
# If we have a dynamic exporter, update its dataset_name property
|
254
|
+
if self.tracer_type == "agentic/llamaindex" and hasattr(self, "dynamic_exporter"):
|
255
|
+
# Update the dataset name in the dynamic exporter
|
256
|
+
self.dynamic_exporter.dataset_name = dataset_name
|
257
|
+
logger.debug(f"Updated dynamic exporter's dataset_name to {dataset_name}")
|
258
|
+
|
259
|
+
# Update the instance variable
|
260
|
+
self.dataset_name = dataset_name
|
261
|
+
|
262
|
+
# Update user_details with new dataset_name
|
263
|
+
self.user_details = self._pass_user_data()
|
264
|
+
|
265
|
+
# Also update the user_details in the dynamic exporter
|
266
|
+
self.dynamic_exporter.user_details = self.user_details
|
267
|
+
else:
|
268
|
+
# Store current parameters
|
269
|
+
current_params = {
|
270
|
+
'project_name': self.project_name,
|
271
|
+
'tracer_type': self.tracer_type,
|
272
|
+
'pipeline': self.pipeline,
|
273
|
+
'metadata': self.metadata,
|
274
|
+
'description': self.description,
|
275
|
+
'upload_timeout': self.upload_timeout
|
276
|
+
}
|
277
|
+
|
278
|
+
# Reinitialize self with new dataset_name and stored parameters
|
279
|
+
self.__init__(
|
280
|
+
dataset_name=dataset_name,
|
281
|
+
**current_params
|
282
|
+
)
|
233
283
|
|
234
284
|
def _improve_metadata(self, metadata, tracer_type):
|
235
285
|
if metadata is None:
|
@@ -375,7 +425,7 @@ class Tracer(AgenticTracing):
|
|
375
425
|
project_name=self.project_name,
|
376
426
|
project_id=self.project_id,
|
377
427
|
dataset_name=self.dataset_name,
|
378
|
-
user_detail=
|
428
|
+
user_detail=self._pass_user_data(),
|
379
429
|
base_url=self.base_url
|
380
430
|
).upload_traces(additional_metadata_keys=additional_metadata_dict)
|
381
431
|
|
@@ -514,6 +564,50 @@ class Tracer(AgenticTracing):
|
|
514
564
|
}
|
515
565
|
return user_detail
|
516
566
|
|
567
|
+
def update_dynamic_exporter(self, **kwargs):
|
568
|
+
"""
|
569
|
+
Update the dynamic exporter's properties.
|
570
|
+
|
571
|
+
Args:
|
572
|
+
**kwargs: Keyword arguments to update. Can include any of the following:
|
573
|
+
- files_to_zip: List of files to zip
|
574
|
+
- project_name: Project name
|
575
|
+
- project_id: Project ID
|
576
|
+
- dataset_name: Dataset name
|
577
|
+
- user_details: User details
|
578
|
+
- base_url: Base URL for API
|
579
|
+
|
580
|
+
Raises:
|
581
|
+
AttributeError: If the tracer_type is not 'agentic/llamaindex' or if the dynamic_exporter is not initialized.
|
582
|
+
"""
|
583
|
+
if self.tracer_type != "agentic/llamaindex" or not hasattr(self, "dynamic_exporter"):
|
584
|
+
raise AttributeError("Dynamic exporter is only available for 'agentic/llamaindex' tracer type")
|
585
|
+
|
586
|
+
for key, value in kwargs.items():
|
587
|
+
if hasattr(self.dynamic_exporter, key):
|
588
|
+
setattr(self.dynamic_exporter, key, value)
|
589
|
+
logger.debug(f"Updated dynamic exporter's {key} to {value}")
|
590
|
+
else:
|
591
|
+
logger.warning(f"Dynamic exporter has no attribute '{key}'")
|
592
|
+
|
593
|
+
def update_file_list(self):
|
594
|
+
"""
|
595
|
+
Update the file list in the dynamic exporter with the latest tracked files.
|
596
|
+
This is useful when new files are added to the project during execution.
|
597
|
+
|
598
|
+
Raises:
|
599
|
+
AttributeError: If the tracer_type is not 'agentic/llamaindex' or if the dynamic_exporter is not initialized.
|
600
|
+
"""
|
601
|
+
if self.tracer_type != "agentic/llamaindex" or not hasattr(self, "dynamic_exporter"):
|
602
|
+
raise AttributeError("Dynamic exporter is only available for 'agentic/llamaindex' tracer type")
|
603
|
+
|
604
|
+
# Get the latest list of unique files
|
605
|
+
list_of_unique_files = self.file_tracker.get_unique_files()
|
606
|
+
|
607
|
+
# Update the dynamic exporter's files_to_zip property
|
608
|
+
self.dynamic_exporter.files_to_zip = list_of_unique_files
|
609
|
+
logger.debug(f"Updated dynamic exporter's files_to_zip with {len(list_of_unique_files)} files")
|
610
|
+
|
517
611
|
def add_context(self, context):
|
518
612
|
"""
|
519
613
|
Add context information to the trace. This method is only supported for 'langchain' and 'llamaindex' tracer types.
|
@@ -0,0 +1,266 @@
|
|
1
|
+
import json
|
2
|
+
import sys
|
3
|
+
from datetime import datetime
|
4
|
+
from typing import final
|
5
|
+
import pytz
|
6
|
+
import uuid
|
7
|
+
from ragaai_catalyst.tracers.agentic_tracing.utils.llm_utils import calculate_llm_cost, get_model_cost
|
8
|
+
|
9
|
+
def convert_time_format(original_time_str, target_timezone_str="Asia/Kolkata"):
|
10
|
+
"""
|
11
|
+
Converts a UTC time string to a specified timezone format.
|
12
|
+
|
13
|
+
Args:
|
14
|
+
original_time_str (str): The original time string in UTC format (e.g., "2025-02-28T22:05:57.945146Z").
|
15
|
+
target_timezone_str (str): The target timezone to convert the time to (default is "Asia/Kolkata").
|
16
|
+
|
17
|
+
Returns:
|
18
|
+
str: The converted time string in the specified timezone format.
|
19
|
+
"""
|
20
|
+
# Parse the original time string into a datetime object
|
21
|
+
utc_time = datetime.strptime(original_time_str, "%Y-%m-%dT%H:%M:%S.%fZ")
|
22
|
+
# Set the timezone to UTC
|
23
|
+
utc_time = utc_time.replace(tzinfo=pytz.UTC)
|
24
|
+
# Convert the UTC time to the target timezone
|
25
|
+
target_timezone = pytz.timezone(target_timezone_str)
|
26
|
+
target_time = utc_time.astimezone(target_timezone)
|
27
|
+
# Format the datetime object to the desired string format
|
28
|
+
formatted_time = target_time.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
|
29
|
+
# Add a colon in the timezone offset for better readability
|
30
|
+
formatted_time = formatted_time[:-2] + ':' + formatted_time[-2:]
|
31
|
+
return formatted_time
|
32
|
+
|
33
|
+
|
34
|
+
def get_uuid(name):
|
35
|
+
"""Generate a random UUID (not based on name)."""
|
36
|
+
return str(uuid.uuid5(uuid.NAMESPACE_DNS, name))
|
37
|
+
|
38
|
+
def get_spans(input_trace, custom_model_cost):
|
39
|
+
data=[]
|
40
|
+
span_type_mapping={"AGENT":"agent","LLM":"llm","TOOL":"tool"}
|
41
|
+
span_name_occurrence = {}
|
42
|
+
for span in input_trace:
|
43
|
+
final_span = {}
|
44
|
+
span_type=span_type_mapping.get(span["attributes"]["openinference.span.kind"],"custom")
|
45
|
+
final_span["id"] = span["context"]["span_id"]
|
46
|
+
if span["name"] not in span_name_occurrence:
|
47
|
+
span_name_occurrence[span['name']]=0
|
48
|
+
else:
|
49
|
+
span_name_occurrence[span['name']]+=1
|
50
|
+
final_span["name"] = span["name"]+"."+str(span_name_occurrence[span['name']])
|
51
|
+
final_span["hash_id"] = get_uuid(final_span["name"])
|
52
|
+
final_span["source_hash_id"] = None
|
53
|
+
final_span["type"] = span_type
|
54
|
+
final_span["start_time"] = convert_time_format(span['start_time'])
|
55
|
+
final_span["end_time"] = convert_time_format(span['end_time'])
|
56
|
+
final_span["parent_id"] = span["parent_id"]
|
57
|
+
final_span["extra_info"] = None
|
58
|
+
'''Handle Error if any'''
|
59
|
+
if span["status"]["status_code"].lower() == "error":
|
60
|
+
final_span["error"] = span["status"]
|
61
|
+
else:
|
62
|
+
final_span["error"] = None
|
63
|
+
# ToDo: Find final trace format for sending error description
|
64
|
+
final_span["metrics"] = []
|
65
|
+
final_span["feedback"] = None
|
66
|
+
final_span["data"]={}
|
67
|
+
final_span["info"]={}
|
68
|
+
final_span["metrics"] =[]
|
69
|
+
final_span["extra_info"]={}
|
70
|
+
if span_type=="agent":
|
71
|
+
if "input.value" in span["attributes"]:
|
72
|
+
try:
|
73
|
+
final_span["data"]["input"] = json.loads(span["attributes"]["input.value"])
|
74
|
+
except Exception as e:
|
75
|
+
final_span["data"]["input"] = span["attributes"]["input.value"]
|
76
|
+
else:
|
77
|
+
final_span["data"]["input"] = ""
|
78
|
+
if "output.value" in span["attributes"]:
|
79
|
+
try:
|
80
|
+
final_span["data"]["output"] = json.loads(span["attributes"]["output.value"])
|
81
|
+
except Exception as e:
|
82
|
+
final_span["data"]["output"] = span["attributes"]["output.value"]
|
83
|
+
else:
|
84
|
+
final_span["data"]["output"] = ""
|
85
|
+
|
86
|
+
elif span_type=="tool":
|
87
|
+
available_fields = list(span['attributes'].keys())
|
88
|
+
tool_fields = [key for key in available_fields if 'tool' in key]
|
89
|
+
if "input.value" in span["attributes"]:
|
90
|
+
try:
|
91
|
+
final_span["data"]["input"] = json.loads(span["attributes"]["input.value"])
|
92
|
+
except Exception as e:
|
93
|
+
final_span["data"]["input"] = span["attributes"]["input.value"]
|
94
|
+
else:
|
95
|
+
final_span["data"]["input"] = ""
|
96
|
+
if "output.value" in span["attributes"]:
|
97
|
+
try:
|
98
|
+
final_span["data"]["output"] = json.loads(span["attributes"]["output.value"])
|
99
|
+
except Exception as e:
|
100
|
+
final_span["data"]["output"] = span["attributes"]["output.value"]
|
101
|
+
else:
|
102
|
+
final_span["data"]["output"] = ""
|
103
|
+
input_data={}
|
104
|
+
for key in tool_fields:
|
105
|
+
input_data[key] = span['attributes'].get(key, None)
|
106
|
+
final_span["info"].update(input_data)
|
107
|
+
|
108
|
+
elif span_type=="llm":
|
109
|
+
available_fields = list(span['attributes'].keys())
|
110
|
+
input_fields = [key for key in available_fields if 'input' in key]
|
111
|
+
input_data = {}
|
112
|
+
for key in input_fields:
|
113
|
+
if 'mime_type' not in key:
|
114
|
+
try:
|
115
|
+
input_data[key] = json.loads(span['attributes'][key])
|
116
|
+
except json.JSONDecodeError as e:
|
117
|
+
input_data[key] = span['attributes'].get(key, None)
|
118
|
+
final_span["data"]["input"] = input_data
|
119
|
+
|
120
|
+
output_fields = [key for key in available_fields if 'output' in key]
|
121
|
+
output_data = {}
|
122
|
+
output_data['content'] = {}
|
123
|
+
for key in output_fields:
|
124
|
+
if 'mime_type' not in key:
|
125
|
+
try:
|
126
|
+
output_data['content'][key] = json.loads(span['attributes'][key])
|
127
|
+
except json.JSONDecodeError as e:
|
128
|
+
output_data['content'][key] = span['attributes'].get(key, None)
|
129
|
+
final_span["data"]["output"] = [output_data]
|
130
|
+
|
131
|
+
if "llm.model_name" in span["attributes"]:
|
132
|
+
final_span["info"]["model"] = span["attributes"]["llm.model_name"]
|
133
|
+
else:
|
134
|
+
final_span["info"]["model"] = None
|
135
|
+
if "llm.invocation_parameters" in span["attributes"]:
|
136
|
+
try:
|
137
|
+
final_span["info"].update(**json.loads(span["attributes"]["llm.invocation_parameters"]))
|
138
|
+
except json.JSONDecodeError as e:
|
139
|
+
print(f"Error in parsing: {e}")
|
140
|
+
|
141
|
+
try:
|
142
|
+
final_span["extra_info"]["llm_parameters"] = json.loads(span["attributes"]["llm.invocation_parameters"])
|
143
|
+
except json.JSONDecodeError as e:
|
144
|
+
final_span["extra_info"]["llm_parameters"] = span["attributes"]["llm.invocation_parameters"]
|
145
|
+
else:
|
146
|
+
final_span["extra_info"]["llm_parameters"] = None
|
147
|
+
|
148
|
+
else:
|
149
|
+
if "input.value" in span["attributes"]:
|
150
|
+
try:
|
151
|
+
final_span["data"]["input"] = json.loads(span["attributes"]["input.value"])
|
152
|
+
except Exception as e:
|
153
|
+
final_span["data"]["input"] = span["attributes"]["input.value"]
|
154
|
+
if "output.value" in span["attributes"]:
|
155
|
+
try:
|
156
|
+
final_span["data"]["output"] = json.loads(span["attributes"]["output.value"])
|
157
|
+
except Exception as e:
|
158
|
+
final_span["data"]["output"] = span["attributes"]["output.value"]
|
159
|
+
|
160
|
+
final_span["info"]["cost"] = {}
|
161
|
+
final_span["info"]["token"] = {}
|
162
|
+
|
163
|
+
if "model" in final_span["info"]:
|
164
|
+
model_name = final_span["info"]["model"]
|
165
|
+
|
166
|
+
model_costs = {
|
167
|
+
"default": {"input_cost_per_token": 0.0, "output_cost_per_token": 0.0}
|
168
|
+
}
|
169
|
+
try:
|
170
|
+
model_costs = get_model_cost()
|
171
|
+
except Exception as e:
|
172
|
+
pass
|
173
|
+
|
174
|
+
if "resource" in span:
|
175
|
+
final_span["info"].update(span["resource"])
|
176
|
+
if "llm.token_count.prompt" in span['attributes']:
|
177
|
+
final_span["info"]["token"]["prompt_tokens"] = span['attributes']['llm.token_count.prompt']
|
178
|
+
if "llm.token_count.completion" in span['attributes']:
|
179
|
+
final_span["info"]["token"]["completion_tokens"] = span['attributes']['llm.token_count.completion']
|
180
|
+
if "llm.token_count.total" in span['attributes']:
|
181
|
+
final_span["info"]["token"]["total_tokens"] = span['attributes']['llm.token_count.total']
|
182
|
+
|
183
|
+
if "info" in final_span:
|
184
|
+
if "token" in final_span["info"]:
|
185
|
+
if "prompt_tokens" in final_span["info"]["token"]:
|
186
|
+
token_usage = {
|
187
|
+
"prompt_tokens": final_span["info"]["token"]["prompt_tokens"],
|
188
|
+
"completion_tokens": final_span["info"]["token"]["completion_tokens"],
|
189
|
+
"total_tokens": final_span["info"]["token"]["total_tokens"]
|
190
|
+
}
|
191
|
+
final_span["info"]["cost"] = calculate_llm_cost(token_usage=token_usage, model_name=model_name, model_costs=model_costs, model_custom_cost=custom_model_cost)
|
192
|
+
data.append(final_span)
|
193
|
+
return data
|
194
|
+
|
195
|
+
def convert_json_format(input_trace, custom_model_cost):
|
196
|
+
"""
|
197
|
+
Converts a JSON from one format to UI format.
|
198
|
+
|
199
|
+
Args:
|
200
|
+
input_trace (str): The input JSON string.
|
201
|
+
|
202
|
+
Returns:
|
203
|
+
final_trace: The converted JSON, or None if an error occurs.
|
204
|
+
"""
|
205
|
+
final_trace = {
|
206
|
+
"id": input_trace[0]["context"]["trace_id"],
|
207
|
+
"trace_name": "",
|
208
|
+
"project_name": "",
|
209
|
+
"start_time": convert_time_format(min(item["start_time"] for item in input_trace)), # Find the minimum start_time of all spans
|
210
|
+
"end_time": convert_time_format(max(item["end_time"] for item in input_trace)) # Find the maximum end_time of all spans
|
211
|
+
}
|
212
|
+
final_trace["metadata"] = {
|
213
|
+
"tokens": {
|
214
|
+
"prompt_tokens": 0.0,
|
215
|
+
"completion_tokens": 0.0,
|
216
|
+
"total_tokens": 0.0
|
217
|
+
},
|
218
|
+
"cost": {
|
219
|
+
"input_cost": 0.0,
|
220
|
+
"output_cost": 0.0,
|
221
|
+
"total_cost": 0.0
|
222
|
+
}
|
223
|
+
}
|
224
|
+
final_trace["replays"]={"source":None}
|
225
|
+
final_trace["data"]=[{}]
|
226
|
+
final_trace["data"][0]["spans"] = get_spans(input_trace, custom_model_cost)
|
227
|
+
final_trace["network_calls"] =[]
|
228
|
+
final_trace["interactions"] = []
|
229
|
+
|
230
|
+
for itr in final_trace["data"][0]["spans"]:
|
231
|
+
if itr["type"]=="llm":
|
232
|
+
if "token" in itr["info"]:
|
233
|
+
if "prompt_tokens" in itr["info"]["token"]:
|
234
|
+
final_trace["metadata"]["tokens"]["prompt_tokens"] += itr["info"]["token"]['prompt_tokens']
|
235
|
+
final_trace["metadata"]["cost"]["input_cost"] += itr["info"]["cost"]['input_cost']
|
236
|
+
if "completion_tokens" in itr["info"]["token"]:
|
237
|
+
final_trace["metadata"]["tokens"]["completion_tokens"] += itr["info"]["token"]['completion_tokens']
|
238
|
+
final_trace["metadata"]["cost"]["output_cost"] += itr["info"]["cost"]['output_cost']
|
239
|
+
if "token" in itr["info"]:
|
240
|
+
if "total_tokens" in itr["info"]["token"]:
|
241
|
+
final_trace["metadata"]["tokens"]["total_tokens"] += itr["info"]["token"]['total_tokens']
|
242
|
+
final_trace["metadata"]["cost"]["total_cost"] += itr["info"]["cost"]['total_cost']
|
243
|
+
|
244
|
+
# get the total tokens, cost
|
245
|
+
final_trace["metadata"]["total_cost"] = final_trace["metadata"]["cost"]["total_cost"]
|
246
|
+
final_trace["metadata"]["total_tokens"] = final_trace["metadata"]["tokens"]["total_tokens"]
|
247
|
+
|
248
|
+
return final_trace
|
249
|
+
|
250
|
+
if __name__ == "__main__":
|
251
|
+
if len(sys.argv) != 3:
|
252
|
+
print("Usage: python convert.py <input_openinference_trace_path> <output_trace_path>")
|
253
|
+
print("Example: python convert.py sample_openinference_trace/test.json output.json")
|
254
|
+
sys.exit(1)
|
255
|
+
input_file_path = sys.argv[1]
|
256
|
+
output_file_path = sys.argv[2]
|
257
|
+
with open(input_file_path,'r') as fin:
|
258
|
+
input_trace=[]
|
259
|
+
for line in fin:
|
260
|
+
data=json.loads(line)
|
261
|
+
input_trace.append(data)
|
262
|
+
payload = convert_json_format(input_trace)
|
263
|
+
print(payload)
|
264
|
+
with open(output_file_path,"w") as fout:
|
265
|
+
json.dump(payload,fout)
|
266
|
+
fout.write("\n")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: ragaai_catalyst
|
3
|
-
Version: 2.1.
|
3
|
+
Version: 2.1.5b37
|
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>, Tushar Kumar <tushar.kumar@raga.ai>
|
6
6
|
Requires-Python: <3.13,>=3.9
|
@@ -38,6 +38,10 @@ Requires-Dist: ipynbname
|
|
38
38
|
Requires-Dist: tiktoken>=0.7.0
|
39
39
|
Requires-Dist: tomli>=2.0.0
|
40
40
|
Requires-Dist: rich>=13.9.4
|
41
|
+
Requires-Dist: openinference-instrumentation-llama-index
|
42
|
+
Requires-Dist: opentelemetry-sdk
|
43
|
+
Requires-Dist: opentelemetry-exporter-otlp
|
44
|
+
Requires-Dist: opentelemetry-proto>=1.12.0
|
41
45
|
Provides-Extra: dev
|
42
46
|
Requires-Dist: pytest; extra == "dev"
|
43
47
|
Requires-Dist: pytest-cov; extra == "dev"
|
@@ -31,7 +31,7 @@ ragaai_catalyst/tracers/distributed.py,sha256=MwlBwIxCAng-OI-7Ove_rkE1mTLeuW4Jw-
|
|
31
31
|
ragaai_catalyst/tracers/langchain_callback.py,sha256=KooENtkX0Hp0S_d_1WI3iH3qNVt-ZcnwOKVlydv4dUk,33518
|
32
32
|
ragaai_catalyst/tracers/llamaindex_callback.py,sha256=ZY0BJrrlz-P9Mg2dX-ZkVKG3gSvzwqBtk7JL_05MiYA,14028
|
33
33
|
ragaai_catalyst/tracers/llamaindex_instrumentation.py,sha256=Ys_jLkvVqo12bKgXDmkp4TxJu9HkBATrFE8cIcTYxWw,14329
|
34
|
-
ragaai_catalyst/tracers/tracer.py,sha256=
|
34
|
+
ragaai_catalyst/tracers/tracer.py,sha256=ZA57OqwDZblU9iPR4Lj5t7gEeqLUmOi_Wa10NxMGQsc,27825
|
35
35
|
ragaai_catalyst/tracers/upload_traces.py,sha256=OKsc-Obf8bJvKBprt3dqj8GQQNkoX3kT_t8TBDi9YDQ,5670
|
36
36
|
ragaai_catalyst/tracers/agentic_tracing/README.md,sha256=X4QwLb7-Jg7GQMIXj-SerZIgDETfw-7VgYlczOR8ZeQ,4508
|
37
37
|
ragaai_catalyst/tracers/agentic_tracing/__init__.py,sha256=yf6SKvOPSpH-9LiKaoLKXwqj5sez8F_5wkOb91yp0oE,260
|
@@ -54,7 +54,7 @@ ragaai_catalyst/tracers/agentic_tracing/tracers/network_tracer.py,sha256=m8CxYkl
|
|
54
54
|
ragaai_catalyst/tracers/agentic_tracing/tracers/tool_tracer.py,sha256=xxrliKPfdfbIZRZqMnUewsaTD8_Hv0dbuoBivNZGD4U,21674
|
55
55
|
ragaai_catalyst/tracers/agentic_tracing/tracers/user_interaction_tracer.py,sha256=bhSUhNQCuJXKjgJAXhjKEYjnHMpYN90FSZdR84fNIKU,4614
|
56
56
|
ragaai_catalyst/tracers/agentic_tracing/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
|
-
ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=
|
57
|
+
ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=Buk0OXjdkku0tuuFzGeqKRtwSeIBe3LpA1oa14qS7v4,12380
|
58
58
|
ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=icycLgfA0734xxoM1rTMG_iIrI3iM94th8RQggJ7sSw,8541
|
59
59
|
ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=aw_eHhUYRbR_9IbIkNjYb7NOsmETD3k1p4a6gxaGI7Q,6462
|
60
60
|
ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py,sha256=m1O8lKpxKwtHofXLW3fTHX5yfqDW5GxoveARlg5cTw4,2571
|
@@ -73,9 +73,11 @@ ragaai_catalyst/tracers/agentic_tracing/utils/system_monitor.py,sha256=H8WNsk4v_
|
|
73
73
|
ragaai_catalyst/tracers/agentic_tracing/utils/trace_utils.py,sha256=go7FVnofviATDph-j8sk2juv09CGSRt1Vq4U868Fhd8,2259
|
74
74
|
ragaai_catalyst/tracers/agentic_tracing/utils/unique_decorator.py,sha256=G027toV-Km20JjKrc-Y_PilQ8ABEKrBvvzgLTnqVg7I,5819
|
75
75
|
ragaai_catalyst/tracers/agentic_tracing/utils/zip_list_of_unique_files.py,sha256=4TeCGsFF26249fV6dJHLTZDrRa93SG9oer4rudoF8Y4,19443
|
76
|
-
ragaai_catalyst/tracers/exporters/__init__.py,sha256=
|
76
|
+
ragaai_catalyst/tracers/exporters/__init__.py,sha256=wQbaqyeIjVZxYprHCKZ9BeiqxeXYBKjzEgP79LWNxCU,293
|
77
|
+
ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py,sha256=dAT2WIvkQLl8RrXdhDwm0NxhxytV6PP4ZViYJ6jlOQg,4553
|
77
78
|
ragaai_catalyst/tracers/exporters/file_span_exporter.py,sha256=RgGteu-NVGprXKkynvyIO5yOjpbtA41R3W_NzCjnkwE,6445
|
78
79
|
ragaai_catalyst/tracers/exporters/raga_exporter.py,sha256=6xvjWXyh8XPkHKSLLmAZUQSvwuyY17ov8pv2VdfI0qA,17875
|
80
|
+
ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=OhPnquuOOxoCtx7cGYdnsQJZ8lNnl0alm3A2Wc4Bl2g,4814
|
79
81
|
ragaai_catalyst/tracers/instrumentators/__init__.py,sha256=FgnMQupoRTzmVsG9YKsLQera2Pfs-AluZv8CxwavoyQ,253
|
80
82
|
ragaai_catalyst/tracers/instrumentators/langchain.py,sha256=yMN0qVF0pUVk6R5M1vJoUXezDo1ejs4klCFRlE8x4vE,574
|
81
83
|
ragaai_catalyst/tracers/instrumentators/llamaindex.py,sha256=SMrRlR4xM7k9HK43hakE8rkrWHxMlmtmWD-AX6TeByc,416
|
@@ -86,9 +88,10 @@ ragaai_catalyst/tracers/utils/convert_llama_instru_callback.py,sha256=8qLo7x4Zsn
|
|
86
88
|
ragaai_catalyst/tracers/utils/extraction_logic_llama_index.py,sha256=ZhPs0YhVtB82-Pq9o1BvCinKE_WPvVxPTEcZjlJbFYM,2371
|
87
89
|
ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py,sha256=XS2_x2qneqEx9oAighLg-LRiueWcESLwIC2r7eJT-Ww,3117
|
88
90
|
ragaai_catalyst/tracers/utils/model_prices_and_context_window_backup.json,sha256=C3uwkibJ08C9sOX-54kulZYmJlIpZ-SQpfE6HNGrjbM,343502
|
91
|
+
ragaai_catalyst/tracers/utils/trace_json_converter.py,sha256=5zeJRD3gY_arfXWGZR4cqAvRhfC_wQUabm_7peiNMdY,12268
|
89
92
|
ragaai_catalyst/tracers/utils/utils.py,sha256=ViygfJ7vZ7U0CTSA1lbxVloHp4NSlmfDzBRNCJuMhis,2374
|
90
|
-
ragaai_catalyst-2.1.
|
91
|
-
ragaai_catalyst-2.1.
|
92
|
-
ragaai_catalyst-2.1.
|
93
|
-
ragaai_catalyst-2.1.
|
94
|
-
ragaai_catalyst-2.1.
|
93
|
+
ragaai_catalyst-2.1.5b37.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
94
|
+
ragaai_catalyst-2.1.5b37.dist-info/METADATA,sha256=B7m2Fu7d9nCZWJmZlM8uXUB7mo3VahUb8s4QuwLbNqw,22060
|
95
|
+
ragaai_catalyst-2.1.5b37.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
96
|
+
ragaai_catalyst-2.1.5b37.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
|
97
|
+
ragaai_catalyst-2.1.5b37.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|