ragaai-catalyst 2.1.5b35__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/tracers/base.py +20 -20
- ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py +221 -547
- 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.5b35.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/METADATA +5 -1
- {ragaai_catalyst-2.1.5b35.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/RECORD +12 -9
- {ragaai_catalyst-2.1.5b35.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/LICENSE +0 -0
- {ragaai_catalyst-2.1.5b35.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/WHEEL +0 -0
- {ragaai_catalyst-2.1.5b35.dist-info → ragaai_catalyst-2.1.5b37.dist-info}/top_level.txt +0 -0
@@ -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.
|