ragaai-catalyst 2.1.7.3b0__py3-none-any.whl → 2.1.7.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.
@@ -157,7 +157,7 @@ def process_upload(task_id: str, filepath: str, hash_id: str, zip_path: str,
157
157
  )
158
158
  logger.info(f"Trace metrics uploaded: {response}")
159
159
  except Exception as e:
160
- logger.error(f"Error uploading trace metrics: {e}")
160
+ logger.error(f"Error uploading trace trace uploader metrics: {e}")
161
161
  # Continue with other uploads
162
162
  else:
163
163
  logger.warning(f"Trace file {filepath} not found, skipping metrics upload")
@@ -364,4 +364,4 @@ if __name__ == "__main__":
364
364
  if args.daemon:
365
365
  logger.info("Daemon mode not needed in futures implementation")
366
366
  else:
367
- logger.info("Interactive mode not needed in futures implementation")
367
+ logger.info("Interactive mode not needed in futures implementation")
@@ -89,7 +89,7 @@ class RAGATraceExporter(SpanExporter):
89
89
  except Exception as e:
90
90
  print(f"Error converting trace {trace_id}: {e}")
91
91
  return # Exit early if conversion fails
92
-
92
+
93
93
  # Check if trace details are None (conversion failed)
94
94
  if ragaai_trace_details is None:
95
95
  logger.error(f"Cannot upload trace {trace_id}: conversion failed and returned None")
@@ -97,7 +97,7 @@ class RAGATraceExporter(SpanExporter):
97
97
 
98
98
  # Upload the trace if upload_trace function is provided
99
99
  try:
100
- if self.post_processor!=None:
100
+ if self.post_processor!=None and self.tracer_type != "langchain":
101
101
  ragaai_trace_details['trace_file_path'] = self.post_processor(ragaai_trace_details['trace_file_path'])
102
102
  if self.tracer_type == "langchain":
103
103
  # Check if we're already in an event loop
@@ -106,18 +106,18 @@ class RAGATraceExporter(SpanExporter):
106
106
  if loop.is_running():
107
107
  # We're in a running event loop (like in Colab/Jupyter)
108
108
  # Create a future and run the coroutine
109
- future = asyncio.ensure_future(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id))
109
+ future = asyncio.ensure_future(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id, self.post_processor))
110
110
  # We don't wait for it to complete as this would block the event loop
111
111
  logger.info(f"Scheduled async upload for trace {trace_id} in existing event loop")
112
112
  else:
113
113
  # No running event loop, use asyncio.run()
114
- asyncio.run(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id))
114
+ asyncio.run(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id, self.post_processor))
115
115
  except RuntimeError:
116
116
  # No event loop exists, create one
117
- asyncio.run(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id))
117
+ asyncio.run(self.upload_rag_trace(ragaai_trace_details, additional_metadata, trace_id, self.post_processor))
118
118
  else:
119
119
  self.upload_trace(ragaai_trace_details, trace_id)
120
- except Exception as e:
120
+ except Exception as e:
121
121
  print(f"Error uploading trace {trace_id}: {e}")
122
122
 
123
123
  def prepare_trace(self, spans, trace_id):
@@ -206,13 +206,16 @@ class RAGATraceExporter(SpanExporter):
206
206
 
207
207
  logger.info(f"Submitted upload task with ID: {self.upload_task_id}")
208
208
 
209
- async def upload_rag_trace(self, ragaai_trace, additional_metadata, trace_id):
209
+ async def upload_rag_trace(self, ragaai_trace, additional_metadata, trace_id, post_processor=None):
210
210
  try:
211
211
  ragaai_trace[0]['external_id'] = self.external_id
212
212
  trace_file_path = os.path.join(self.tmp_dir, f"{trace_id}.json")
213
213
  with open(trace_file_path, 'w') as f:
214
214
  json.dump(ragaai_trace, f, indent=2)
215
215
  logger.info(f"Trace file saved at {trace_file_path}")
216
+ if self.post_processor!=None:
217
+ trace_file_path = self.post_processor(trace_file_path)
218
+ logger.info(f"After post processing Trace file saved at {trace_file_path}")
216
219
 
217
220
  # Create a ThreadPoolExecutor with max_workers=30
218
221
  with concurrent.futures.ThreadPoolExecutor(max_workers=self.max_upload_workers) as executor:
@@ -227,7 +230,7 @@ class RAGATraceExporter(SpanExporter):
227
230
  base_url=self.base_url
228
231
  ).upload_traces,
229
232
  additional_metadata_keys=additional_metadata
230
- )
233
+ )
231
234
 
232
235
  # Implement retry logic - attempt upload up to 3 times
233
236
  max_retries = 3
@@ -427,12 +427,20 @@ class Tracer(AgenticTracing):
427
427
  with open(original_path, 'r') as f:
428
428
  data = json.load(f)
429
429
 
430
- # Apply masking only to data['data']
431
- data['data'] = recursive_mask_values(data['data'])
432
-
433
- # Create new filename with 'processed_' prefix in /var/tmp/
430
+ # Apply masking only to data['data'] or in case of langchain rag apply on 'traces' field of each element
431
+ if 'data' in data:
432
+ data['data'] = recursive_mask_values(data['data'])
433
+ elif isinstance(data,list):
434
+ masked_traces = []
435
+ for item in data:
436
+ if isinstance(item, dict) and 'traces' in item:
437
+ item['traces'] = recursive_mask_values(item['traces'])
438
+ masked_traces.append(item)
439
+ data = masked_traces
440
+ # Create new filename with 'processed_' prefix
434
441
  new_filename = f"processed_{original_path.name}"
435
- final_trace_json_path = Path("/var/tmp") / new_filename
442
+ dir_name, original_filename = os.path.split(original_trace_json_path)
443
+ final_trace_json_path = Path(dir_name) / new_filename
436
444
 
437
445
  # Write modified data to the new file
438
446
  with open(final_trace_json_path, 'w') as f:
@@ -538,7 +546,7 @@ class Tracer(AgenticTracing):
538
546
 
539
547
  def _improve_metadata(self, metadata, tracer_type):
540
548
  if metadata is None:
541
- metadata = {"metadata": {}}
549
+ metadata = {}
542
550
  metadata.setdefault("log_source", f"{tracer_type}_tracer")
543
551
  metadata.setdefault("recorded_on", str(datetime.datetime.now()))
544
552
  return metadata
@@ -859,3 +867,30 @@ class Tracer(AgenticTracing):
859
867
  self.user_context = context
860
868
  else:
861
869
  raise TypeError("context must be a string")
870
+
871
+ def add_metadata(self, metadata):
872
+ """
873
+ Add metadata information to the trace. This method is only supported for 'langchain' and 'llamaindex' tracer types.
874
+
875
+ Args:
876
+ metadata: Additional metadata information to be added to the trace. Can be a dictionary.
877
+
878
+ Raises:
879
+ ValueError: If tracer_type is not 'langchain' or 'llamaindex'.
880
+ """
881
+ if self.tracer_type not in ["langchain", "llamaindex"]:
882
+ raise ValueError("add_metadata is only supported for 'langchain' and 'llamaindex' tracer types")
883
+
884
+ # Convert string metadata to string if needed
885
+ user_details = self.user_details
886
+ user_metadata = user_details["trace_user_detail"]["metadata"]
887
+ if isinstance(metadata, dict):
888
+ for key, value in metadata.items():
889
+ if key in user_metadata:
890
+ user_metadata[key] = value
891
+ else:
892
+ raise ValueError(f"Key '{key}' not found in metadata")
893
+ self.dynamic_exporter.user_details = user_details
894
+ self.metadata = user_metadata
895
+ else:
896
+ raise TypeError("metadata must be a dictionary")
@@ -36,15 +36,23 @@ class UploadTraces:
36
36
  "model_name": {"columnType": "metadata"},
37
37
  "total_cost": {"columnType": "metadata", "dataType": "numerical"},
38
38
  "total_latency": {"columnType": "metadata", "dataType": "numerical"},
39
+ "error": {"columnType": "metadata"}
39
40
  }
40
41
 
41
42
  if additional_metadata_keys:
42
43
  for key in additional_metadata_keys:
43
44
  if key == "model_name":
44
45
  SCHEMA_MAPPING_NEW['response']["modelName"] = additional_metadata_keys[key]
46
+ elif key == "error":
47
+ pass
45
48
  else:
46
49
  SCHEMA_MAPPING_NEW[key] = {"columnType": key, "parentColumn": "response"}
47
50
 
51
+ if self.user_detail and self.user_detail["trace_user_detail"]["metadata"]:
52
+ for key in self.user_detail["trace_user_detail"]["metadata"]:
53
+ if key not in SCHEMA_MAPPING_NEW:
54
+ SCHEMA_MAPPING_NEW[key] = {"columnType": "metadata"}
55
+
48
56
  if additional_pipeline_keys:
49
57
  for key in additional_pipeline_keys:
50
58
  SCHEMA_MAPPING_NEW[key] = {"columnType": "pipeline"}
@@ -58,4 +58,5 @@ def convert_langchain_callbacks_output(result, project_name="", metadata="", pip
58
58
 
59
59
  initial_struc[0]["traces"] = traces_data
60
60
 
61
+ initial_struc[0]["error"] = result["error"]
61
62
  return initial_struc
@@ -164,10 +164,30 @@ def rag_trace_json_converter(input_trace, custom_model_cost, trace_id, user_deta
164
164
  except Exception as e:
165
165
  logger.error(f"Error while extracting context from trace: {str(e)}")
166
166
  return ""
167
-
167
+
168
+ def get_span_errors(input_trace):
169
+ try:
170
+ if tracer_type == "langchain":
171
+ span_errors = {}
172
+ for span in input_trace:
173
+ try:
174
+ if "status" in span.keys() and span.get("status", {}).get("status_code", "").lower() == "error":
175
+ span_errors[f"{span['name']}"] = span["status"]
176
+ except:
177
+ logger.error(f"Error fetching status from span")
178
+ return span_errors
179
+ except:
180
+ logger.error(f"Error in get_span_errors")
181
+ return None
182
+
183
+
184
+
185
+
186
+
168
187
  prompt = get_prompt(input_trace)
169
188
  response = get_response(input_trace)
170
189
  context = get_context(input_trace)
190
+ error = get_span_errors(input_trace)
171
191
 
172
192
  if tracer_type == "langchain":
173
193
  trace_aggregate["tracer_type"] = "langchain"
@@ -183,6 +203,7 @@ def rag_trace_json_converter(input_trace, custom_model_cost, trace_id, user_deta
183
203
  trace_aggregate["data"]["prompt"] = prompt
184
204
  trace_aggregate["data"]["response"] = response
185
205
  trace_aggregate["data"]["context"] = context
206
+ trace_aggregate["error"] = error
186
207
 
187
208
  if tracer_type == "langchain":
188
209
  additional_metadata = get_additional_metadata(input_trace, custom_model_cost, model_cost, prompt, response)
@@ -191,6 +212,9 @@ def rag_trace_json_converter(input_trace, custom_model_cost, trace_id, user_deta
191
212
 
192
213
  trace_aggregate["metadata"] = user_details.get("trace_user_detail", {}).get("metadata")
193
214
  trace_aggregate["metadata"].update(additional_metadata)
215
+ trace_aggregate["metadata"]["error"] = f"{error}"
216
+ additional_metadata["error"] = error if error else None
217
+
194
218
  additional_metadata.pop("total_cost")
195
219
  additional_metadata.pop("total_latency")
196
220
  return trace_aggregate, additional_metadata
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragaai_catalyst
3
- Version: 2.1.7.3b0
3
+ Version: 2.1.7.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>
6
6
  Requires-Python: <=3.13.2,>=3.10
@@ -31,8 +31,8 @@ ragaai_catalyst/tracers/distributed.py,sha256=MwlBwIxCAng-OI-7Ove_rkE1mTLeuW4Jw-
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=LHRd35rTFgYovxsI4tyXHgsCCdccO1_O1txFLFyLUKc,39069
35
- ragaai_catalyst/tracers/upload_traces.py,sha256=PEE_JhAmOAMKyb-pl4ZoFWhIePxJm1zs93crrk94iEg,5887
34
+ ragaai_catalyst/tracers/tracer.py,sha256=pKHP5PK4au9Gdis-anYmu2PTmqWc4tNDrJvZWWRLQVo,40753
35
+ ragaai_catalyst/tracers/upload_traces.py,sha256=8T9j2FEUYEoMMU9hW8DbYRG7KtL-QAyCDucuD5gHUzA,6278
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
38
38
  ragaai_catalyst/tracers/agentic_tracing/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -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=Tv_QMg8EIQyoDwFnDqKlNwmJVBJNkdr6-es3UT-Mugg,12939
57
+ ragaai_catalyst/tracers/agentic_tracing/upload/trace_uploader.py,sha256=qGinKWnb-NSEfIfIOsL37tB9AS8-dKa_-nNNHkUmtuE,12955
58
58
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=9s1cXH1rZ2EMPMsJ7zls8BRVVHdyGNXK-SoIF7P2MxM,8595
59
59
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=bRJGqdLPm0fTORAdUGRo0aDPiZeqB30gK_iC7SsymL4,6603
60
60
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py,sha256=m1O8lKpxKwtHofXLW3fTHX5yfqDW5GxoveARlg5cTw4,2571
@@ -77,19 +77,19 @@ ragaai_catalyst/tracers/exporters/__init__.py,sha256=wQbaqyeIjVZxYprHCKZ9BeiqxeX
77
77
  ragaai_catalyst/tracers/exporters/dynamic_trace_exporter.py,sha256=v2V-y1l9t9gQQbqoi2jlEhm1xRQjR5yTyr6rxSriXCE,6303
78
78
  ragaai_catalyst/tracers/exporters/file_span_exporter.py,sha256=RgGteu-NVGprXKkynvyIO5yOjpbtA41R3W_NzCjnkwE,6445
79
79
  ragaai_catalyst/tracers/exporters/raga_exporter.py,sha256=6xvjWXyh8XPkHKSLLmAZUQSvwuyY17ov8pv2VdfI0qA,17875
80
- ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=BzL5u7yOcWHHtPueoJclXcvexBQo1SFu5lHY8ANnzP8,12998
80
+ ragaai_catalyst/tracers/exporters/ragaai_trace_exporter.py,sha256=C88pZ_n4mNv1Fc3qOOOm5JQdoTvQzHcjS7mSImslQ0I,13313
81
81
  ragaai_catalyst/tracers/instrumentators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  ragaai_catalyst/tracers/utils/__init__.py,sha256=KeMaZtYaTojilpLv65qH08QmpYclfpacDA0U3wg6Ybw,64
83
- ragaai_catalyst/tracers/utils/convert_langchain_callbacks_output.py,sha256=e0URuRWCdzpxuBLfL82FOTMjbRuDAkW8aIRi7s7Nocc,1655
83
+ ragaai_catalyst/tracers/utils/convert_langchain_callbacks_output.py,sha256=SehrD7q8ytAiUYoWr406b4mWs3Lk0Rcy6Ekkihh22TI,1703
84
84
  ragaai_catalyst/tracers/utils/convert_llama_instru_callback.py,sha256=8qLo7x4Zsn3dhJfSv9gviB60YXZ2TOsWEouucJmBM0c,1724
85
85
  ragaai_catalyst/tracers/utils/extraction_logic_llama_index.py,sha256=ZhPs0YhVtB82-Pq9o1BvCinKE_WPvVxPTEcZjlJbFYM,2371
86
86
  ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py,sha256=XS2_x2qneqEx9oAighLg-LRiueWcESLwIC2r7eJT-Ww,3117
87
87
  ragaai_catalyst/tracers/utils/model_prices_and_context_window_backup.json,sha256=C3uwkibJ08C9sOX-54kulZYmJlIpZ-SQpfE6HNGrjbM,343502
88
- ragaai_catalyst/tracers/utils/rag_trace_json_converter.py,sha256=jwScK9bo0NGpaOgeII-m2l_ovcHNo9Pd2wkZHFBt0zc,18559
88
+ ragaai_catalyst/tracers/utils/rag_trace_json_converter.py,sha256=adCKk7Nj8307XYYg2sB-QT-66OShOs2iTGwNVwqbHig,19373
89
89
  ragaai_catalyst/tracers/utils/trace_json_converter.py,sha256=E0_QfciQMMpCtQYrNB4l8HJhlaFalr5bkMqkVRgQahY,14073
90
90
  ragaai_catalyst/tracers/utils/utils.py,sha256=ViygfJ7vZ7U0CTSA1lbxVloHp4NSlmfDzBRNCJuMhis,2374
91
- ragaai_catalyst-2.1.7.3b0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
92
- ragaai_catalyst-2.1.7.3b0.dist-info/METADATA,sha256=5TXfNHsBByRy9NfLRp8vCsmedgGXJpq0qc_18g43HYA,17607
93
- ragaai_catalyst-2.1.7.3b0.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
94
- ragaai_catalyst-2.1.7.3b0.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
95
- ragaai_catalyst-2.1.7.3b0.dist-info/RECORD,,
91
+ ragaai_catalyst-2.1.7.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
92
+ ragaai_catalyst-2.1.7.4.dist-info/METADATA,sha256=YyOec5GmUSf51XzWsaaY7xCDwAv_l2ILcbFQd7PP4YI,17605
93
+ ragaai_catalyst-2.1.7.4.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
94
+ ragaai_catalyst-2.1.7.4.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
95
+ ragaai_catalyst-2.1.7.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.1)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5