ragaai-catalyst 2.2.3b5__py3-none-any.whl → 2.2.4__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/synthetic_data_generation.py +1 -1
- ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py +260 -46
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py +38 -10
- ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py +1 -0
- ragaai_catalyst/tracers/tracer.py +12 -38
- ragaai_catalyst/tracers/utils/trace_json_converter.py +3 -3
- {ragaai_catalyst-2.2.3b5.dist-info → ragaai_catalyst-2.2.4.dist-info}/METADATA +1 -1
- {ragaai_catalyst-2.2.3b5.dist-info → ragaai_catalyst-2.2.4.dist-info}/RECORD +11 -11
- {ragaai_catalyst-2.2.3b5.dist-info → ragaai_catalyst-2.2.4.dist-info}/WHEEL +0 -0
- {ragaai_catalyst-2.2.3b5.dist-info → ragaai_catalyst-2.2.4.dist-info}/licenses/LICENSE +0 -0
- {ragaai_catalyst-2.2.3b5.dist-info → ragaai_catalyst-2.2.4.dist-info}/top_level.txt +0 -0
@@ -517,7 +517,7 @@ class SyntheticDataGeneration:
|
|
517
517
|
str: The extracted text content from the CSV, with each row joined and separated by newlines.
|
518
518
|
"""
|
519
519
|
text = ""
|
520
|
-
with open(file_path, 'r', encoding='utf-8') as file:
|
520
|
+
with open(file_path, 'r', encoding='utf-8', errors="ignore") as file:
|
521
521
|
csv_reader = csv.reader(file)
|
522
522
|
for row in csv_reader:
|
523
523
|
text += " ".join(row) + "\n"
|
@@ -19,6 +19,8 @@ import glob
|
|
19
19
|
from logging.handlers import RotatingFileHandler
|
20
20
|
import concurrent.futures
|
21
21
|
from typing import Dict, Any, Optional
|
22
|
+
import threading
|
23
|
+
import uuid
|
22
24
|
|
23
25
|
# Set up logging
|
24
26
|
log_dir = os.path.join(tempfile.gettempdir(), "ragaai_logs")
|
@@ -65,19 +67,52 @@ STATUS_FAILED = "failed"
|
|
65
67
|
|
66
68
|
# Global executor for handling uploads
|
67
69
|
_executor = None
|
70
|
+
_executor_lock = threading.Lock()
|
68
71
|
# Dictionary to track futures and their associated task IDs
|
69
72
|
_futures: Dict[str, Any] = {}
|
73
|
+
_futures_lock = threading.Lock()
|
70
74
|
|
71
|
-
|
75
|
+
|
76
|
+
_cleanup_lock = threading.Lock()
|
77
|
+
_last_cleanup = 0
|
78
|
+
CLEANUP_INTERVAL = 300 # 5 minutes
|
79
|
+
|
80
|
+
# Thread-safe counter for task IDs
|
81
|
+
_task_counter = 0
|
82
|
+
_task_counter_lock = threading.Lock()
|
83
|
+
|
84
|
+
def get_executor(max_workers=None):
|
72
85
|
"""Get or create the thread pool executor"""
|
73
86
|
global _executor
|
74
|
-
|
75
|
-
_executor
|
76
|
-
|
87
|
+
with _executor_lock:
|
88
|
+
if _executor is None:
|
89
|
+
# Calculate optimal worker count
|
90
|
+
if max_workers is None:
|
91
|
+
max_workers = min(32, (os.cpu_count() or 1) * 4)
|
92
|
+
|
93
|
+
logger.info(f"Creating ThreadPoolExecutor with {max_workers} workers")
|
94
|
+
_executor = concurrent.futures.ThreadPoolExecutor(
|
95
|
+
max_workers=max_workers,
|
96
|
+
thread_name_prefix="trace_uploader"
|
97
|
+
)
|
98
|
+
# atexit.register(shutdown)
|
99
|
+
return _executor
|
100
|
+
|
101
|
+
|
102
|
+
def generate_unique_task_id():
|
103
|
+
"""Generate a thread-safe unique task ID"""
|
104
|
+
global _task_counter
|
105
|
+
|
106
|
+
with _task_counter_lock:
|
107
|
+
_task_counter += 1
|
108
|
+
counter = _task_counter
|
109
|
+
|
110
|
+
unique_id = str(uuid.uuid4())[:8] # Short UUID
|
111
|
+
return f"task_{int(time.time())}_{os.getpid()}_{counter}_{unique_id}"
|
77
112
|
|
78
113
|
def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
79
114
|
project_name: str, project_id: str, dataset_name: str,
|
80
|
-
user_details: Dict[str, Any], base_url: str, timeout=120) -> Dict[str, Any]:
|
115
|
+
user_details: Dict[str, Any], base_url: str, timeout=120, fail_on_trace_error=True) -> Dict[str, Any]:
|
81
116
|
"""
|
82
117
|
Process a single upload task
|
83
118
|
|
@@ -91,7 +126,7 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
|
91
126
|
dataset_name: Dataset name
|
92
127
|
user_details: User details dictionary
|
93
128
|
base_url: Base URL for API calls
|
94
|
-
|
129
|
+
fail_on_trace_error: If True, raise exception when trace upload fails
|
95
130
|
Returns:
|
96
131
|
Dict containing status and any error information
|
97
132
|
"""
|
@@ -176,13 +211,31 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
|
176
211
|
base_url=base_url,
|
177
212
|
timeout=timeout
|
178
213
|
)
|
179
|
-
upload_traces.upload_agentic_traces()
|
180
|
-
|
214
|
+
upload_success = upload_traces.upload_agentic_traces()
|
215
|
+
if upload_success:
|
216
|
+
logger.info("Agentic traces uploaded successfully")
|
217
|
+
else:
|
218
|
+
error_msg = "Agentic traces upload failed"
|
219
|
+
logger.error(error_msg)
|
220
|
+
|
221
|
+
if fail_on_trace_error:
|
222
|
+
result["status"] = STATUS_FAILED
|
223
|
+
result["error"] = error_msg
|
224
|
+
result["end_time"] = datetime.now().isoformat()
|
225
|
+
save_task_status(result)
|
181
226
|
except Exception as e:
|
182
227
|
logger.error(f"Error uploading agentic traces: {e}")
|
228
|
+
|
183
229
|
# Continue with code upload
|
184
230
|
else:
|
231
|
+
error_msg = f"Trace file {filepath} not found"
|
185
232
|
logger.warning(f"Trace file {filepath} not found, skipping traces upload")
|
233
|
+
if fail_on_trace_error:
|
234
|
+
result["status"] = STATUS_FAILED
|
235
|
+
result["error"] = error_msg
|
236
|
+
result["end_time"] = datetime.now().isoformat()
|
237
|
+
save_task_status(result)
|
238
|
+
logger.error(error_msg)
|
186
239
|
|
187
240
|
# Step 4: Upload code hash
|
188
241
|
if hash_id and zip_path and os.path.exists(zip_path):
|
@@ -217,6 +270,31 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
|
|
217
270
|
save_task_status(result)
|
218
271
|
return result
|
219
272
|
|
273
|
+
def cleanup_completed_futures():
|
274
|
+
"""Remove completed futures to prevent memory leaks"""
|
275
|
+
global _futures, _last_cleanup
|
276
|
+
|
277
|
+
current_time = time.time()
|
278
|
+
if current_time - _last_cleanup < CLEANUP_INTERVAL:
|
279
|
+
return
|
280
|
+
|
281
|
+
with _cleanup_lock:
|
282
|
+
if current_time - _last_cleanup < CLEANUP_INTERVAL:
|
283
|
+
return # Double-check after acquiring lock
|
284
|
+
with _futures_lock:
|
285
|
+
completed_tasks = []
|
286
|
+
for task_id, future in _futures.items():
|
287
|
+
if future.done():
|
288
|
+
completed_tasks.append(task_id)
|
289
|
+
|
290
|
+
for task_id in completed_tasks:
|
291
|
+
del _futures[task_id]
|
292
|
+
|
293
|
+
_last_cleanup = current_time
|
294
|
+
|
295
|
+
if completed_tasks:
|
296
|
+
logger.info(f"Cleaned up {len(completed_tasks)} completed futures")
|
297
|
+
|
220
298
|
def save_task_status(task_status: Dict[str, Any]):
|
221
299
|
"""Save task status to a file"""
|
222
300
|
task_id = task_status["task_id"]
|
@@ -253,38 +331,82 @@ def submit_upload_task(filepath, hash_id, zip_path, project_name, project_id, da
|
|
253
331
|
filepath = os.path.abspath(filepath)
|
254
332
|
logger.debug(f"Using absolute filepath: {filepath}")
|
255
333
|
|
256
|
-
# Generate a unique task ID
|
257
|
-
task_id =
|
334
|
+
# Generate a thread-safe unique task ID
|
335
|
+
task_id = generate_unique_task_id()
|
336
|
+
logger.debug(f"Generated task ID: {task_id}")
|
337
|
+
|
338
|
+
# Function to handle synchronous processing
|
339
|
+
def do_sync_processing():
|
340
|
+
try:
|
341
|
+
logger.info(f"Processing task {task_id} synchronously...")
|
342
|
+
result = process_upload(
|
343
|
+
task_id=task_id,
|
344
|
+
filepath=filepath,
|
345
|
+
hash_id=hash_id,
|
346
|
+
zip_path=zip_path,
|
347
|
+
project_name=project_name,
|
348
|
+
project_id=project_id,
|
349
|
+
dataset_name=dataset_name,
|
350
|
+
user_details=user_details,
|
351
|
+
base_url=base_url,
|
352
|
+
timeout=timeout,
|
353
|
+
fail_on_trace_error=True
|
354
|
+
)
|
355
|
+
logger.info(f"Synchronous processing completed for {task_id}: {result}")
|
356
|
+
return task_id
|
357
|
+
except Exception as e:
|
358
|
+
logger.error(f"Error in synchronous processing: {e}")
|
359
|
+
return None
|
258
360
|
|
259
|
-
#
|
361
|
+
# Try to get the executor
|
260
362
|
executor = get_executor()
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
363
|
+
if executor is None:
|
364
|
+
logger.warning("Executor is None or shutdown in progress, processing synchronously")
|
365
|
+
return do_sync_processing()
|
366
|
+
# Cleanup completed futures periodically
|
367
|
+
# cleanup_completed_futures()
|
368
|
+
# Try to submit the task to the executor
|
369
|
+
try:
|
370
|
+
# Cleanup completed futures periodically
|
371
|
+
future = executor.submit(
|
372
|
+
process_upload,
|
373
|
+
task_id=task_id,
|
374
|
+
filepath=filepath,
|
375
|
+
hash_id=hash_id,
|
376
|
+
zip_path=zip_path,
|
377
|
+
project_name=project_name,
|
378
|
+
project_id=project_id,
|
379
|
+
dataset_name=dataset_name,
|
380
|
+
user_details=user_details,
|
381
|
+
base_url=base_url,
|
382
|
+
timeout=timeout,
|
383
|
+
fail_on_trace_error=True
|
384
|
+
)
|
385
|
+
|
386
|
+
# Store the future for later status checks
|
387
|
+
with _futures_lock:
|
388
|
+
_futures[task_id] = future
|
389
|
+
|
390
|
+
# Create initial status
|
391
|
+
initial_status = {
|
392
|
+
"task_id": task_id,
|
393
|
+
"status": STATUS_PENDING,
|
394
|
+
"error": None,
|
395
|
+
"start_time": datetime.now().isoformat()
|
396
|
+
}
|
397
|
+
save_task_status(initial_status)
|
398
|
+
|
399
|
+
return task_id
|
400
|
+
except RuntimeError as e:
|
401
|
+
if "cannot schedule new futures after shutdown" in str(e):
|
402
|
+
logger.warning(f"Executor already shut down, falling back to synchronous processing: {e}")
|
403
|
+
return do_sync_processing()
|
404
|
+
else:
|
405
|
+
logger.error(f"Error submitting task: {e}")
|
406
|
+
return None
|
407
|
+
except Exception as e:
|
408
|
+
logger.error(f"Error submitting task: {e}")
|
409
|
+
return None
|
288
410
|
|
289
411
|
def get_task_status(task_id):
|
290
412
|
"""
|
@@ -299,7 +421,8 @@ def get_task_status(task_id):
|
|
299
421
|
logger.debug(f"Getting status for task {task_id}")
|
300
422
|
|
301
423
|
# Check if we have a future for this task
|
302
|
-
|
424
|
+
with _futures_lock:
|
425
|
+
future = _futures.get(task_id)
|
303
426
|
|
304
427
|
# If we have a future, check its status
|
305
428
|
if future:
|
@@ -328,13 +451,104 @@ def get_task_status(task_id):
|
|
328
451
|
|
329
452
|
return {"status": "unknown", "error": "Task not found"}
|
330
453
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
454
|
+
|
455
|
+
def get_upload_queue_status():
|
456
|
+
"""Get detailed status of upload queue"""
|
457
|
+
logger.info("Reached get queue status")
|
458
|
+
# with _executor_lock:
|
459
|
+
executor = get_executor()
|
460
|
+
|
461
|
+
if executor is None:
|
462
|
+
return {
|
463
|
+
"total_submitted": 0,
|
464
|
+
"pending_uploads": 0,
|
465
|
+
"completed_uploads": 0,
|
466
|
+
"failed_uploads": 0,
|
467
|
+
"thread_pool_queue_size": 0,
|
468
|
+
"active_workers": 0,
|
469
|
+
"max_workers": 0
|
470
|
+
}
|
471
|
+
# with _futures_lock:
|
472
|
+
pending_count = len([f for f in _futures.values() if not f.done()])
|
473
|
+
completed_count = len([f for f in _futures.values() if f.done() and not f.exception()])
|
474
|
+
failed_count = len([f for f in _futures.values() if f.done() and f.exception()])
|
475
|
+
|
476
|
+
# Try to get thread pool queue size (may not be available in all Python versions)
|
477
|
+
queue_size = 0
|
478
|
+
try:
|
479
|
+
if hasattr(executor, '_work_queue'):
|
480
|
+
queue_size = executor._work_queue.qsize()
|
481
|
+
except:
|
482
|
+
pass
|
483
|
+
|
484
|
+
return {
|
485
|
+
"total_submitted": len(_futures),
|
486
|
+
"pending_uploads": pending_count,
|
487
|
+
"completed_uploads": completed_count,
|
488
|
+
"failed_uploads": failed_count,
|
489
|
+
"thread_pool_queue_size": queue_size,
|
490
|
+
"active_workers": getattr(executor, '_threads', set()).__len__() if executor else 0,
|
491
|
+
"max_workers": executor._max_workers if executor else 0
|
492
|
+
}
|
493
|
+
|
494
|
+
|
495
|
+
def shutdown(timeout=120):
|
496
|
+
"""Enhanced shutdown with manual timeout and progress reporting"""
|
497
|
+
logger.debug("Reached shutdown of executor")
|
498
|
+
global _executor, _futures
|
499
|
+
with _executor_lock:
|
500
|
+
if _executor is None:
|
501
|
+
logger.debug("Executor is none in shutdown")
|
502
|
+
return
|
503
|
+
|
504
|
+
# Log current state
|
505
|
+
status = get_upload_queue_status()
|
506
|
+
logger.debug(f"Queue status: {status}")
|
507
|
+
logger.debug(f"Shutting down uploader. Pending uploads: {status['pending_uploads']}")
|
508
|
+
|
509
|
+
if status['pending_uploads'] > 0:
|
510
|
+
logger.debug(f"Waiting up to {timeout}s for {status['pending_uploads']} uploads to complete...")
|
511
|
+
|
512
|
+
start_time = time.time()
|
513
|
+
last_report = start_time
|
514
|
+
|
515
|
+
while time.time() - start_time < timeout:
|
516
|
+
# Check if all futures are done
|
517
|
+
with _futures_lock:
|
518
|
+
pending_futures = [f for f in _futures.values() if not f.done()]
|
519
|
+
|
520
|
+
if not pending_futures:
|
521
|
+
logger.info("All uploads completed successfully")
|
522
|
+
break
|
523
|
+
|
524
|
+
# Report progress every 10 seconds
|
525
|
+
current_time = time.time()
|
526
|
+
if current_time - last_report >= 10:
|
527
|
+
elapsed = current_time - start_time
|
528
|
+
remaining = timeout - elapsed
|
529
|
+
logger.info(f"Still waiting for {len(pending_futures)} uploads to complete. "
|
530
|
+
f"Time remaining: {remaining:.1f}s")
|
531
|
+
last_report = current_time
|
532
|
+
|
533
|
+
# Sleep briefly to avoid busy waiting
|
534
|
+
time.sleep(0.5)
|
535
|
+
else:
|
536
|
+
# Timeout reached
|
537
|
+
logger.info("Executor timeout reached")
|
538
|
+
with _futures_lock:
|
539
|
+
pending_futures = [f for f in _futures.values() if not f.done()]
|
540
|
+
logger.debug(f"Shutdown timeout reached. {len(pending_futures)} uploads still pending.")
|
541
|
+
else:
|
542
|
+
logger.info(f"No pending uploads")
|
543
|
+
|
544
|
+
# Shutdown the executor
|
545
|
+
try:
|
546
|
+
_executor.shutdown(wait=False) # Don't wait here since we already waited above
|
547
|
+
logger.info("Executor shutdown initiated")
|
548
|
+
except Exception as e:
|
549
|
+
logger.error(f"Error during executor shutdown: {e}")
|
550
|
+
|
551
|
+
_executor = None
|
338
552
|
|
339
553
|
# Register shutdown handler
|
340
554
|
atexit.register(shutdown)
|
@@ -144,7 +144,7 @@ class UploadAgenticTraces:
|
|
144
144
|
payload = f.read().replace("\n", "").replace("\r", "").encode()
|
145
145
|
except Exception as e:
|
146
146
|
print(f"Error while reading file: {e}")
|
147
|
-
return
|
147
|
+
return False
|
148
148
|
try:
|
149
149
|
start_time = time.time()
|
150
150
|
response = requests.request(
|
@@ -156,9 +156,10 @@ class UploadAgenticTraces:
|
|
156
156
|
)
|
157
157
|
if response.status_code != 200 or response.status_code != 201:
|
158
158
|
return response, response.status_code
|
159
|
+
return True
|
159
160
|
except requests.exceptions.RequestException as e:
|
160
161
|
print(f"Error while uploading to presigned url: {e}")
|
161
|
-
return
|
162
|
+
return False
|
162
163
|
|
163
164
|
def insert_traces(self, presignedUrl):
|
164
165
|
headers = {
|
@@ -185,7 +186,7 @@ class UploadAgenticTraces:
|
|
185
186
|
)
|
186
187
|
if response.status_code != 200:
|
187
188
|
print(f"Error inserting traces: {response.json()['message']}")
|
188
|
-
return
|
189
|
+
return False
|
189
190
|
elif response.status_code == 401:
|
190
191
|
logger.warning("Received 401 error. Attempting to refresh token.")
|
191
192
|
token = RagaAICatalyst.get_token(force_refresh=True)
|
@@ -207,10 +208,12 @@ class UploadAgenticTraces:
|
|
207
208
|
)
|
208
209
|
if response.status_code != 200:
|
209
210
|
print(f"Error inserting traces: {response.json()['message']}")
|
210
|
-
return
|
211
|
+
return False
|
211
212
|
else:
|
212
213
|
print("Error while inserting traces")
|
213
|
-
return
|
214
|
+
return False
|
215
|
+
else:
|
216
|
+
return True
|
214
217
|
except requests.exceptions.RequestException as e:
|
215
218
|
print(f"Error while inserting traces: {e}")
|
216
219
|
return None
|
@@ -247,10 +250,35 @@ class UploadAgenticTraces:
|
|
247
250
|
|
248
251
|
def upload_agentic_traces(self):
|
249
252
|
try:
|
250
|
-
|
251
|
-
if
|
252
|
-
|
253
|
-
|
254
|
-
|
253
|
+
presigned_url = self._get_presigned_url()
|
254
|
+
if presigned_url is None:
|
255
|
+
print("Warning: Failed to obtain presigned URL")
|
256
|
+
return False
|
257
|
+
|
258
|
+
# Upload the file using the presigned URL
|
259
|
+
upload_result = self._put_presigned_url(presigned_url, self.json_file_path)
|
260
|
+
if not upload_result:
|
261
|
+
print("Error: Failed to upload file to presigned URL")
|
262
|
+
return False
|
263
|
+
elif isinstance(upload_result, tuple):
|
264
|
+
response, status_code = upload_result
|
265
|
+
if status_code not in [200, 201]:
|
266
|
+
print(
|
267
|
+
f"Error: Upload failed with status code {status_code}: {response.text if hasattr(response, 'text') else 'Unknown error'}")
|
268
|
+
return False
|
269
|
+
# Insert trace records
|
270
|
+
insert_success = self.insert_traces(presigned_url)
|
271
|
+
if not insert_success:
|
272
|
+
print("Error: Failed to insert trace records")
|
273
|
+
return False
|
274
|
+
|
275
|
+
print("Successfully uploaded agentic traces")
|
276
|
+
return True
|
277
|
+
except FileNotFoundError:
|
278
|
+
print(f"Error: Trace file not found at {self.json_file_path}")
|
279
|
+
return False
|
280
|
+
except ConnectionError as e:
|
281
|
+
print(f"Error: Network connection failed while uploading traces: {e}")
|
282
|
+
return False
|
255
283
|
except Exception as e:
|
256
284
|
print(f"Error while uploading agentic traces: {e}")
|
@@ -76,6 +76,7 @@ class RAGATraceExporter(SpanExporter):
|
|
76
76
|
|
77
77
|
def shutdown(self):
|
78
78
|
# Process any remaining traces during shutdown
|
79
|
+
logger.debug("Reached shutdown of exporter")
|
79
80
|
for trace_id, spans in self.trace_spans.items():
|
80
81
|
self.process_complete_trace(spans, trace_id)
|
81
82
|
self.trace_spans.clear()
|
@@ -510,47 +510,12 @@ class Tracer(AgenticTracing):
|
|
510
510
|
|
511
511
|
def set_dataset_name(self, dataset_name):
|
512
512
|
"""
|
513
|
-
|
514
|
-
If using agentic/llamaindex tracer with dynamic exporter, update the exporter's dataset_name property.
|
515
|
-
|
513
|
+
This method updates the dataset_name attribute of the dynamic exporter.
|
516
514
|
Args:
|
517
515
|
dataset_name (str): The new dataset name to set
|
518
516
|
"""
|
519
|
-
|
520
|
-
|
521
|
-
# Update the dataset name in the dynamic exporter
|
522
|
-
self.dynamic_exporter.dataset_name = dataset_name
|
523
|
-
logger.debug(f"Updated dynamic exporter's dataset_name to {dataset_name}")
|
524
|
-
|
525
|
-
# Update the instance variable
|
526
|
-
self.dataset_name = dataset_name
|
527
|
-
|
528
|
-
# Update user_details with new dataset_name
|
529
|
-
self.user_details = self._pass_user_data()
|
530
|
-
|
531
|
-
# Also update the user_details in the dynamic exporter
|
532
|
-
self.dynamic_exporter.user_details = self.user_details
|
533
|
-
else:
|
534
|
-
current_params = {
|
535
|
-
'project_name': self.project_name,
|
536
|
-
'trace_name': self.trace_name,
|
537
|
-
'tracer_type': self.tracer_type,
|
538
|
-
'pipeline': self.pipeline,
|
539
|
-
'metadata': self.metadata,
|
540
|
-
'description': self.description,
|
541
|
-
'timeout': self.timeout,
|
542
|
-
'update_llm_cost': self.update_llm_cost,
|
543
|
-
'auto_instrumentation': self.auto_instrumentation,
|
544
|
-
'interval_time': self.interval_time,
|
545
|
-
'max_upload_workers': self.max_upload_workers,
|
546
|
-
'external_id': self.external_id
|
547
|
-
}
|
548
|
-
|
549
|
-
# Reinitialize self with new dataset_name and stored parameters
|
550
|
-
self.__init__(
|
551
|
-
dataset_name=dataset_name,
|
552
|
-
**current_params
|
553
|
-
)
|
517
|
+
self.dynamic_exporter.dataset_name = dataset_name
|
518
|
+
logger.debug(f"Updated dynamic exporter's dataset_name to {dataset_name}")
|
554
519
|
|
555
520
|
def _improve_metadata(self, metadata, tracer_type):
|
556
521
|
if metadata is None:
|
@@ -919,3 +884,12 @@ class Tracer(AgenticTracing):
|
|
919
884
|
self.metadata = user_metadata
|
920
885
|
else:
|
921
886
|
logger.warning("metadata must be a dictionary")
|
887
|
+
|
888
|
+
def set_project_name(self, project_name):
|
889
|
+
"""
|
890
|
+
This method updates the project_name attribute of the dynamic exporter.
|
891
|
+
Args:
|
892
|
+
project_name (str): The new project name to set
|
893
|
+
"""
|
894
|
+
self.dynamic_exporter.project_name = project_name
|
895
|
+
logger.debug(f"Updated dynamic exporter's project_name to {project_name}")
|
@@ -156,14 +156,14 @@ def convert_json_format(
|
|
156
156
|
|
157
157
|
# If prompt tokens or/and completion tokens are not present, will calculate it using tiktoken
|
158
158
|
try:
|
159
|
-
if prompt_tokens == 0:
|
159
|
+
if prompt_tokens == 0 and span["attributes"].get("openinference.span.kind") == "LLM" and span["status"].get("status_code") != "ERROR":
|
160
160
|
prompt_value = span["attributes"].get("input.value")
|
161
161
|
if prompt_value:
|
162
162
|
prompt_tokens = count_tokens(prompt_value)
|
163
163
|
logger.debug(
|
164
164
|
f"Prompt tokens not present, calculated it: {prompt_tokens}"
|
165
165
|
)
|
166
|
-
if completion_tokens == 0:
|
166
|
+
if completion_tokens == 0 and span["attributes"].get("openinference.span.kind") == "LLM" and span["status"].get("status_code") != "ERROR" :
|
167
167
|
completion_value = span["attributes"].get("output.value")
|
168
168
|
if completion_value:
|
169
169
|
completion_tokens = count_tokens(completion_value)
|
@@ -189,7 +189,7 @@ def convert_json_format(
|
|
189
189
|
model_name = next((name for name in reversed(model_names) if name), "")
|
190
190
|
if not model_name and span["attributes"].get("openinference.span.kind")=="LLM":
|
191
191
|
model_name = json.loads(span["attributes"].get("metadata", "")).get("ls_model_name", "")
|
192
|
-
if model_name:
|
192
|
+
if model_name and span["attributes"].get("openinference.span.kind") == "LLM":
|
193
193
|
try:
|
194
194
|
model_costs = get_model_cost()
|
195
195
|
span_cost = calculate_llm_cost(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ragaai_catalyst
|
3
|
-
Version: 2.2.
|
3
|
+
Version: 2.2.4
|
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>, Rishabh Pandey <rishabh.pandey@raga.ai>, Jyotsana C G <jyotsana@raga.ai>
|
6
6
|
Requires-Python: <=3.13.2,>=3.10
|
@@ -10,7 +10,7 @@ ragaai_catalyst/prompt_manager.py,sha256=W8ypramzOprrJ7-22d5vkBXIuIQ8v9XAzKDGxKs
|
|
10
10
|
ragaai_catalyst/proxy_call.py,sha256=CHxldeceZUaLU-to_hs_Kf1z_b2vHMssLS_cOBedu78,5499
|
11
11
|
ragaai_catalyst/ragaai_catalyst.py,sha256=ZlcpOgJA9lVRi51YFy4dVfsxU0I79LJu0MnVI5BIL-c,25201
|
12
12
|
ragaai_catalyst/redteaming_old.py,sha256=W2d89Ok8W-C8g7TBM3fDIFLof3q9FuYSr0jcryH2XQo,7097
|
13
|
-
ragaai_catalyst/synthetic_data_generation.py,sha256=
|
13
|
+
ragaai_catalyst/synthetic_data_generation.py,sha256=AumjIzKk-Uvn7RQGatpx7TPvlI4NjU-rUiVFockoGNg,37969
|
14
14
|
ragaai_catalyst/utils.py,sha256=TlhEFwLyRU690HvANbyoRycR3nQ67lxVUQoUOfTPYQ0,3772
|
15
15
|
ragaai_catalyst/redteaming/__init__.py,sha256=TJdvZpaZGFsg9qKONdjTosSVLZGadYFpHG6KE0xapKU,155
|
16
16
|
ragaai_catalyst/redteaming/evaluator.py,sha256=C50SAc3RsR7PZnz-VQ7wQfDpiVEb7T3W3KV4Lj0tWYE,4599
|
@@ -31,7 +31,7 @@ ragaai_catalyst/tracers/distributed.py,sha256=CGPuOh4CsgEk428PPibieLaAG2Tt3BVygF
|
|
31
31
|
ragaai_catalyst/tracers/langchain_callback.py,sha256=CB75zzG3-DkYTELj0vI1MOHQTY0MuQJfoHIXz9Cl8S8,34568
|
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=hxVJN45CtIeU8Dc5G1kreXJa7Vv_3buBAHVz-Q3buKo,41435
|
35
35
|
ragaai_catalyst/tracers/upload_traces.py,sha256=w1clGGfdOMpStUJX40NAlxe6dcFdN4pwcezyII0bGYA,6994
|
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,8 +54,8 @@ 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=
|
58
|
-
ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=
|
57
|
+
ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=iMUMFR9XVipCBunpv8_No8bCoP3lqG47M5dg-ugibWo,21006
|
58
|
+
ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=t3spo5w7TyfR0Zeqm1h5Z-bJ-BlZ3EPGTvRdK5lpFpE,11705
|
59
59
|
ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=2mxdi7k_SoDqQUFo1oQ__28CpmSIvVugYcbuRltUK9Q,9920
|
60
60
|
ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py,sha256=m1O8lKpxKwtHofXLW3fTHX5yfqDW5GxoveARlg5cTw4,2571
|
61
61
|
ragaai_catalyst/tracers/agentic_tracing/utils/__init__.py,sha256=XdB3X_ufe4RVvGorxSqAiB9dYv4UD7Hvvuw3bsDUppY,60
|
@@ -76,7 +76,7 @@ ragaai_catalyst/tracers/exporters/__init__.py,sha256=wQbaqyeIjVZxYprHCKZ9BeiqxeX
|
|
76
76
|
ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py,sha256=Rm-QaLv1qMAKpHKcFOcK_HWaKHwFBoUH45_4QYipE-g,6843
|
77
77
|
ragaai_catalyst/tracers/exporters/file_span_exporter.py,sha256=NZsD3rShUiC3rO9y3Y2vqEtS3MO51FXZy0p3q9cdDNY,6403
|
78
78
|
ragaai_catalyst/tracers/exporters/raga_exporter.py,sha256=l-RfysTIXYxtvYkVlJbRvg-AzJbT4Fdb-YiZh0mfuDs,17868
|
79
|
-
ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=
|
79
|
+
ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=VLvlWFRFPhE32WrF-_J_vCczduz13WAcOW8MKDgDYJc,8979
|
80
80
|
ragaai_catalyst/tracers/instrumentators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
81
|
ragaai_catalyst/tracers/utils/__init__.py,sha256=KeMaZtYaTojilpLv65qH08QmpYclfpacDA0U3wg6Ybw,64
|
82
82
|
ragaai_catalyst/tracers/utils/convert_langchain_callbacks_output.py,sha256=SehrD7q8ytAiUYoWr406b4mWs3Lk0Rcy6Ekkihh22TI,1703
|
@@ -86,10 +86,10 @@ ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py,sha256=XS2_x2
|
|
86
86
|
ragaai_catalyst/tracers/utils/model_prices_and_context_window_backup.json,sha256=WlZCZeOQ54aMVjYS8BAeka2uaFC3ftBTMZ8zzzA8TAI,495947
|
87
87
|
ragaai_catalyst/tracers/utils/rag_extraction_logic_final.py,sha256=3ygkRT__lLDRflRttjzPu28tIA8cTCiGQVMQjqMItqQ,11309
|
88
88
|
ragaai_catalyst/tracers/utils/rag_trace_json_converter.py,sha256=54IEZO-YRjUAahV5nw8KClXqTF1LhfDry_TsZ4KGow4,20467
|
89
|
-
ragaai_catalyst/tracers/utils/trace_json_converter.py,sha256
|
89
|
+
ragaai_catalyst/tracers/utils/trace_json_converter.py,sha256=-HZVmijeUFLO7e9OAvi1RJdWVTxPRUHPd1MkKQlCD54,11785
|
90
90
|
ragaai_catalyst/tracers/utils/utils.py,sha256=o-p9n2ZuophdrV0wrixu-BqRHCkovup_klc3mS8mU8g,2374
|
91
|
-
ragaai_catalyst-2.2.
|
92
|
-
ragaai_catalyst-2.2.
|
93
|
-
ragaai_catalyst-2.2.
|
94
|
-
ragaai_catalyst-2.2.
|
95
|
-
ragaai_catalyst-2.2.
|
91
|
+
ragaai_catalyst-2.2.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
92
|
+
ragaai_catalyst-2.2.4.dist-info/METADATA,sha256=AwtPailq1qhPswbvc0UdO7YyEQ_NekEWXWZfK5RaNeU,17677
|
93
|
+
ragaai_catalyst-2.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
94
|
+
ragaai_catalyst-2.2.4.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
|
95
|
+
ragaai_catalyst-2.2.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|