ragaai-catalyst 2.0.7.1__py3-none-any.whl → 2.0.7.2__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.
@@ -8,6 +8,7 @@ import pdb
8
8
 
9
9
  logger = logging.getLogger(__name__)
10
10
 
11
+
11
12
  class Evaluation:
12
13
 
13
14
  def __init__(self, project_name, dataset_name):
@@ -16,7 +17,7 @@ class Evaluation:
16
17
  self.base_url = f"{RagaAICatalyst.BASE_URL}"
17
18
  self.timeout = 10
18
19
  self.jobId = None
19
- self.num_projects=99999
20
+ self.num_projects = 99999
20
21
 
21
22
  try:
22
23
  response = requests.get(
@@ -34,9 +35,11 @@ class Evaluation:
34
35
  ]
35
36
  if project_name not in project_list:
36
37
  raise ValueError("Project not found. Please enter a valid project name")
37
-
38
+
38
39
  self.project_id = [
39
- project["id"] for project in response.json()["data"]["content"] if project["name"] == project_name
40
+ project["id"]
41
+ for project in response.json()["data"]["content"]
42
+ if project["name"] == project_name
40
43
  ][0]
41
44
 
42
45
  except requests.exceptions.RequestException as e:
@@ -46,44 +49,55 @@ class Evaluation:
46
49
  try:
47
50
 
48
51
  headers = {
49
- 'Content-Type': 'application/json',
52
+ "Content-Type": "application/json",
50
53
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
51
54
  "X-Project-Id": str(self.project_id),
52
55
  }
53
- json_data = {"size": 12, "page": "0", "projectId": str(self.project_id), "search": ""}
56
+ json_data = {
57
+ "size": 12,
58
+ "page": "0",
59
+ "projectId": str(self.project_id),
60
+ "search": "",
61
+ }
54
62
  response = requests.post(
55
63
  f"{self.base_url}/v2/llm/dataset",
56
64
  headers=headers,
57
65
  json=json_data,
58
66
  timeout=self.timeout,
59
67
  )
60
-
68
+
61
69
  response.raise_for_status()
62
70
  datasets_content = response.json()["data"]["content"]
63
71
  dataset_list = [dataset["name"] for dataset in datasets_content]
64
72
 
65
73
  if dataset_name not in dataset_list:
66
74
  raise ValueError("Dataset not found. Please enter a valid dataset name")
67
-
68
- self.dataset_id = [dataset["id"] for dataset in datasets_content if dataset["name"]==dataset_name][0]
75
+
76
+ self.dataset_id = [
77
+ dataset["id"]
78
+ for dataset in datasets_content
79
+ if dataset["name"] == dataset_name
80
+ ][0]
69
81
 
70
82
  except requests.exceptions.RequestException as e:
71
83
  logger.error(f"Failed to retrieve dataset list: {e}")
72
84
  raise
73
85
 
74
-
75
86
  def list_metrics(self):
76
87
  headers = {
77
88
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
78
- 'X-Project-Id': str(self.project_id),
89
+ "X-Project-Id": str(self.project_id),
79
90
  }
80
91
  try:
81
92
  response = requests.get(
82
- f'{self.base_url}/v1/llm/llm-metrics',
93
+ f"{self.base_url}/v1/llm/llm-metrics",
83
94
  headers=headers,
84
- timeout=self.timeout)
95
+ timeout=self.timeout,
96
+ )
85
97
  response.raise_for_status()
86
- metric_names = [metric["name"] for metric in response.json()["data"]["metrics"]]
98
+ metric_names = [
99
+ metric["name"] for metric in response.json()["data"]["metrics"]
100
+ ]
87
101
  return metric_names
88
102
  except requests.exceptions.HTTPError as http_err:
89
103
  logger.error(f"HTTP error occurred: {http_err}")
@@ -100,22 +114,35 @@ class Evaluation:
100
114
  def _get_dataset_id_based_on_dataset_type(self, metric_to_evaluate):
101
115
  try:
102
116
  headers = {
103
- 'Content-Type': 'application/json',
117
+ "Content-Type": "application/json",
104
118
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
105
119
  "X-Project-Id": str(self.project_id),
106
120
  }
107
- json_data = {"size": 12, "page": "0", "projectId": str(self.project_id), "search": ""}
121
+ json_data = {
122
+ "size": 12,
123
+ "page": "0",
124
+ "projectId": str(self.project_id),
125
+ "search": "",
126
+ }
108
127
  response = requests.post(
109
128
  f"{self.base_url}/v2/llm/dataset",
110
129
  headers=headers,
111
130
  json=json_data,
112
131
  timeout=self.timeout,
113
132
  )
114
-
133
+
115
134
  response.raise_for_status()
116
135
  datasets_content = response.json()["data"]["content"]
117
- dataset = [dataset for dataset in datasets_content if dataset["name"]==self.dataset_name][0]
118
- if (dataset["datasetType"]=="prompt" and metric_to_evaluate=="prompt") or (dataset["datasetType"]=="chat" and metric_to_evaluate=="chat") or dataset["datasetType"]==None:
136
+ dataset = [
137
+ dataset
138
+ for dataset in datasets_content
139
+ if dataset["name"] == self.dataset_name
140
+ ][0]
141
+ if (
142
+ (dataset["datasetType"] == "prompt" and metric_to_evaluate == "prompt")
143
+ or (dataset["datasetType"] == "chat" and metric_to_evaluate == "chat")
144
+ or dataset["datasetType"] == None
145
+ ):
119
146
  return dataset["id"]
120
147
  else:
121
148
  return dataset["derivedDatasetId"]
@@ -123,28 +150,24 @@ class Evaluation:
123
150
  logger.error(f"Failed to retrieve dataset list: {e}")
124
151
  raise
125
152
 
126
-
127
153
  def _get_dataset_schema(self, metric_to_evaluate=None):
128
- #this dataset_id is based on which type of metric_to_evaluate
129
- data_set_id=self._get_dataset_id_based_on_dataset_type(metric_to_evaluate)
130
- self.dataset_id=data_set_id
154
+ # this dataset_id is based on which type of metric_to_evaluate
155
+ data_set_id = self._get_dataset_id_based_on_dataset_type(metric_to_evaluate)
156
+ self.dataset_id = data_set_id
131
157
 
132
158
  headers = {
133
159
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
134
- 'Content-Type': 'application/json',
135
- 'X-Project-Id': str(self.project_id),
136
- }
137
- data = {
138
- "datasetId": str(data_set_id),
139
- "fields": [],
140
- "rowFilterList": []
160
+ "Content-Type": "application/json",
161
+ "X-Project-Id": str(self.project_id),
141
162
  }
163
+ data = {"datasetId": str(data_set_id), "fields": [], "rowFilterList": []}
142
164
  try:
143
165
  response = requests.post(
144
- f'{self.base_url}/v1/llm/docs',
166
+ f"{self.base_url}/v1/llm/docs",
145
167
  headers=headers,
146
168
  json=data,
147
- timeout=self.timeout)
169
+ timeout=self.timeout,
170
+ )
148
171
  response.raise_for_status()
149
172
  if response.status_code == 200:
150
173
  return response.json()["data"]["columns"]
@@ -160,31 +183,35 @@ class Evaluation:
160
183
  logger.error(f"An unexpected error occurred: {e}")
161
184
  return {}
162
185
 
163
-
164
- def _get_variablename_from_user_schema_mapping(self, schemaName, metric_name, schema_mapping, metric_to_evaluate):
186
+ def _get_variablename_from_user_schema_mapping(
187
+ self, schemaName, metric_name, schema_mapping, metric_to_evaluate
188
+ ):
165
189
  user_dataset_schema = self._get_dataset_schema(metric_to_evaluate)
166
190
  user_dataset_columns = [item["displayName"] for item in user_dataset_schema]
167
191
  variableName = None
168
192
  for key, val in schema_mapping.items():
169
- if "".join(val.split("_")).lower()==schemaName:
193
+ if "".join(val.split("_")).lower() == schemaName:
170
194
  if key in user_dataset_columns:
171
- variableName=key
195
+ variableName = key
172
196
  else:
173
- raise ValueError(f"Column '{key}' is not present in '{self.dataset_name}' dataset")
197
+ raise ValueError(
198
+ f"Column '{key}' is not present in '{self.dataset_name}' dataset"
199
+ )
174
200
  if variableName:
175
201
  return variableName
176
202
  else:
177
- raise ValueError(f"Map '{schemaName}' column in schema_mapping for {metric_name} metric evaluation")
178
-
203
+ raise ValueError(
204
+ f"Map '{schemaName}' column in schema_mapping for {metric_name} metric evaluation"
205
+ )
179
206
 
180
207
  def _get_mapping(self, metric_name, metrics_schema, schema_mapping):
181
-
208
+
182
209
  mapping = []
183
210
  for schema in metrics_schema:
184
- if schema["name"]==metric_name:
211
+ if schema["name"] == metric_name:
185
212
  requiredFields = schema["config"]["requiredFields"]
186
213
 
187
- #this is added to check if "Chat" column is required for metric evaluation
214
+ # this is added to check if "Chat" column is required for metric evaluation
188
215
  required_variables = [_["name"].lower() for _ in requiredFields]
189
216
  if "chat" in required_variables:
190
217
  metric_to_evaluate = "chat"
@@ -193,38 +220,42 @@ class Evaluation:
193
220
 
194
221
  for field in requiredFields:
195
222
  schemaName = field["name"]
196
- variableName = self._get_variablename_from_user_schema_mapping(schemaName.lower(), metric_name, schema_mapping, metric_to_evaluate)
197
- mapping.append({"schemaName": schemaName, "variableName": variableName})
223
+ variableName = self._get_variablename_from_user_schema_mapping(
224
+ schemaName.lower(),
225
+ metric_name,
226
+ schema_mapping,
227
+ metric_to_evaluate,
228
+ )
229
+ mapping.append(
230
+ {"schemaName": schemaName, "variableName": variableName}
231
+ )
198
232
  return mapping
199
233
 
200
234
  def _get_metricParams(self):
201
235
  return {
202
- "metricSpec": {
203
- "name": "metric_to_evaluate",
204
- "config": {
205
- "model": "null",
206
- "params": {
207
- "model": {
208
- "value": ""
209
- }
210
- },
211
- "mappings": "mappings"
212
- },
213
- "displayName": "displayName"
236
+ "metricSpec": {
237
+ "name": "metric_to_evaluate",
238
+ "config": {
239
+ "model": "null",
240
+ "params": {"model": {"value": ""}},
241
+ "mappings": "mappings",
214
242
  },
215
- "rowFilterList": []
216
- }
217
-
243
+ "displayName": "displayName",
244
+ },
245
+ "rowFilterList": [],
246
+ }
247
+
218
248
  def _get_metrics_schema_response(self):
219
249
  headers = {
220
250
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
221
- 'X-Project-Id': str(self.project_id),
251
+ "X-Project-Id": str(self.project_id),
222
252
  }
223
253
  try:
224
254
  response = requests.get(
225
- f'{self.base_url}/v1/llm/llm-metrics',
255
+ f"{self.base_url}/v1/llm/llm-metrics",
226
256
  headers=headers,
227
- timeout=self.timeout)
257
+ timeout=self.timeout,
258
+ )
228
259
  response.raise_for_status()
229
260
  metrics_schema = [metric for metric in response.json()["data"]["metrics"]]
230
261
  return metrics_schema
@@ -242,42 +273,49 @@ class Evaluation:
242
273
 
243
274
  def _update_base_json(self, metrics):
244
275
  metrics_schema_response = self._get_metrics_schema_response()
245
- sub_providers = ["openai","azure","gemini","groq"]
276
+ sub_providers = ["openai", "azure", "gemini", "groq", "anthropic", "bedrock"]
246
277
  metricParams = []
247
278
  for metric in metrics:
248
279
  base_json = self._get_metricParams()
249
280
  base_json["metricSpec"]["name"] = metric["name"]
250
-
251
- #pasing model configuration
281
+
282
+ # pasing model configuration
252
283
  for key, value in metric["config"].items():
253
- #checking if provider is one of the allowed providers
254
- if key.lower()=="provider" and value.lower() not in sub_providers:
255
- raise ValueError("Enter a valid provider name. The following Provider names are supported: OpenAI, Azure, Gemini, Groq")
256
-
257
- if key.lower()=="threshold":
258
- if len(value)>1:
259
- raise ValueError("'threshold' can only take one argument gte/lte/eq")
284
+ # checking if provider is one of the allowed providers
285
+ if key.lower() == "provider" and value.lower() not in sub_providers:
286
+ raise ValueError(
287
+ "Enter a valid provider name. The following Provider names are supported: openai, azure, gemini, groq, anthropic, bedrock"
288
+ )
289
+
290
+ if key.lower() == "threshold":
291
+ if len(value) > 1:
292
+ raise ValueError(
293
+ "'threshold' can only take one argument gte/lte/eq"
294
+ )
260
295
  else:
261
296
  for key_thres, value_thres in value.items():
262
- base_json["metricSpec"]["config"]["params"][key] = {f"{key_thres}":value_thres}
297
+ base_json["metricSpec"]["config"]["params"][key] = {
298
+ f"{key_thres}": value_thres
299
+ }
263
300
  else:
264
301
  base_json["metricSpec"]["config"]["params"][key] = {"value": value}
265
302
 
266
-
267
303
  # if metric["config"]["model"]:
268
304
  # base_json["metricSpec"]["config"]["params"]["model"]["value"] = metric["config"]["model"]
269
305
  base_json["metricSpec"]["displayName"] = metric["column_name"]
270
- mappings = self._get_mapping(metric["name"], metrics_schema_response, metric["schema_mapping"])
306
+ mappings = self._get_mapping(
307
+ metric["name"], metrics_schema_response, metric["schema_mapping"]
308
+ )
271
309
  base_json["metricSpec"]["config"]["mappings"] = mappings
272
310
  metricParams.append(base_json)
273
- metric_schema_mapping = {"datasetId":self.dataset_id}
311
+ metric_schema_mapping = {"datasetId": self.dataset_id}
274
312
  metric_schema_mapping["metricParams"] = metricParams
275
313
  return metric_schema_mapping
276
314
 
277
315
  def _get_executed_metrics_list(self):
278
316
  headers = {
279
317
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
280
- 'X-Project-Id': str(self.project_id),
318
+ "X-Project-Id": str(self.project_id),
281
319
  }
282
320
  try:
283
321
  response = requests.get(
@@ -288,7 +326,9 @@ class Evaluation:
288
326
  response.raise_for_status()
289
327
  dataset_columns = response.json()["data"]["datasetColumnsResponses"]
290
328
  dataset_columns = [item["displayName"] for item in dataset_columns]
291
- executed_metric_list = [data for data in dataset_columns if not data.startswith('_')]
329
+ executed_metric_list = [
330
+ data for data in dataset_columns if not data.startswith("_")
331
+ ]
292
332
 
293
333
  return executed_metric_list
294
334
  except requests.exceptions.HTTPError as http_err:
@@ -304,7 +344,7 @@ class Evaluation:
304
344
  return []
305
345
 
306
346
  def add_metrics(self, metrics):
307
- #Handle required key if missing
347
+ # Handle required key if missing
308
348
  required_keys = {"name", "config", "column_name", "schema_mapping"}
309
349
  for metric in metrics:
310
350
  missing_keys = required_keys - metric.keys()
@@ -323,18 +363,18 @@ class Evaluation:
323
363
  raise ValueError(f"Column name '{column_name}' already exists.")
324
364
 
325
365
  headers = {
326
- 'Content-Type': 'application/json',
366
+ "Content-Type": "application/json",
327
367
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
328
- 'X-Project-Id': str(self.project_id),
368
+ "X-Project-Id": str(self.project_id),
329
369
  }
330
370
  metric_schema_mapping = self._update_base_json(metrics)
331
371
  try:
332
372
  response = requests.post(
333
- f'{self.base_url}/playground/metric-evaluation',
334
- headers=headers,
373
+ f"{self.base_url}/playground/metric-evaluation",
374
+ headers=headers,
335
375
  json=metric_schema_mapping,
336
- timeout=self.timeout
337
- )
376
+ timeout=self.timeout,
377
+ )
338
378
  if response.status_code == 400:
339
379
  raise ValueError(response.json()["message"])
340
380
  response.raise_for_status()
@@ -355,24 +395,31 @@ class Evaluation:
355
395
 
356
396
  def get_status(self):
357
397
  headers = {
358
- 'Content-Type': 'application/json',
398
+ "Content-Type": "application/json",
359
399
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
360
- 'X-Project-Id': str(self.project_id),
400
+ "X-Project-Id": str(self.project_id),
361
401
  }
362
402
  try:
363
403
  response = requests.get(
364
- f'{self.base_url}/job/status',
365
- headers=headers,
366
- timeout=self.timeout)
404
+ f"{self.base_url}/job/status", headers=headers, timeout=self.timeout
405
+ )
367
406
  response.raise_for_status()
368
407
  if response.json()["success"]:
369
- status_json = [item["status"] for item in response.json()["data"]["content"] if item["id"]==self.jobId][0]
408
+ status_json = [
409
+ item["status"]
410
+ for item in response.json()["data"]["content"]
411
+ if item["id"] == self.jobId
412
+ ][0]
370
413
  if status_json == "Failed":
371
414
  return print("Job failed. No results to fetch.")
372
415
  elif status_json == "In Progress":
373
- return print(f"Job in progress. Please wait while the job completes.\nVisit Job Status: {self.base_url.removesuffix('/api')}/projects/job-status?projectId={self.project_id} to track")
416
+ return print(
417
+ f"Job in progress. Please wait while the job completes.\nVisit Job Status: {self.base_url.removesuffix('/api')}/projects/job-status?projectId={self.project_id} to track"
418
+ )
374
419
  elif status_json == "Completed":
375
- print(f"Job completed. Fetching results.\nVisit Job Status: {self.base_url.removesuffix('/api')}/projects/job-status?projectId={self.project_id} to check")
420
+ print(
421
+ f"Job completed. Fetching results.\nVisit Job Status: {self.base_url.removesuffix('/api')}/projects/job-status?projectId={self.project_id} to check"
422
+ )
376
423
  except requests.exceptions.HTTPError as http_err:
377
424
  logger.error(f"HTTP error occurred: {http_err}")
378
425
  except requests.exceptions.ConnectionError as conn_err:
@@ -388,25 +435,24 @@ class Evaluation:
388
435
 
389
436
  def get_presignedUrl():
390
437
  headers = {
391
- 'Content-Type': 'application/json',
438
+ "Content-Type": "application/json",
392
439
  "Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
393
- 'X-Project-Id': str(self.project_id),
394
- }
395
-
440
+ "X-Project-Id": str(self.project_id),
441
+ }
442
+
396
443
  data = {
397
- "fields": [
398
- "*"
399
- ],
444
+ "fields": ["*"],
400
445
  "datasetId": str(self.dataset_id),
401
446
  "rowFilterList": [],
402
- "export": True
403
- }
404
- try:
447
+ "export": True,
448
+ }
449
+ try:
405
450
  response = requests.post(
406
- f'{self.base_url}/v1/llm/docs',
407
- headers=headers,
451
+ f"{self.base_url}/v1/llm/docs",
452
+ headers=headers,
408
453
  json=data,
409
- timeout=self.timeout)
454
+ timeout=self.timeout,
455
+ )
410
456
  response.raise_for_status()
411
457
  return response.json()
412
458
  except requests.exceptions.HTTPError as http_err:
@@ -445,8 +491,8 @@ class Evaluation:
445
491
  df = pd.read_csv(io.StringIO(response_text))
446
492
 
447
493
  column_list = df.columns.to_list()
448
- column_list = [col for col in column_list if not col.startswith('_')]
449
- column_list = [col for col in column_list if '.' not in col]
494
+ column_list = [col for col in column_list if not col.startswith("_")]
495
+ column_list = [col for col in column_list if "." not in col]
450
496
  return df[column_list]
451
497
  else:
452
498
  return pd.DataFrame()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ragaai_catalyst
3
- Version: 2.0.7.1
3
+ Version: 2.0.7.2
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>
6
6
  Requires-Python: >=3.9
@@ -1,7 +1,7 @@
1
1
  ragaai_catalyst/__init__.py,sha256=BdIJ_UUre0uEnRTsLw_hE0C0muWk6XWNZqdVOel22R4,537
2
2
  ragaai_catalyst/_version.py,sha256=JKt9KaVNOMVeGs8ojO6LvIZr7ZkMzNN-gCcvryy4x8E,460
3
3
  ragaai_catalyst/dataset.py,sha256=j_vu3Xkp_8qYW0J9Qnn53Uyh98MsugqYl5zxhOv9EOg,10731
4
- ragaai_catalyst/evaluation.py,sha256=EZGISQH6vGB7vP5OmUBRXmEqkqZPIYN_eEUUz1jTrJ8,20285
4
+ ragaai_catalyst/evaluation.py,sha256=hKwa8C8TE4IhCpkf5vrLhY2Y3TLajqa5s2-JqVGHoQo,21087
5
5
  ragaai_catalyst/experiment.py,sha256=8KvqgJg5JVnt9ghhGDJvdb4mN7ETBX_E5gNxBT0Nsn8,19010
6
6
  ragaai_catalyst/guard_executor.py,sha256=llPbE3DyVtrybojXknzBZj8-dtUrGBQwi9-ZiPJxGRo,3762
7
7
  ragaai_catalyst/guardrails_manager.py,sha256=DILMOAASK57FH9BLq_8yC1AQzRJ8McMFLwCXgYwNAd4,11904
@@ -23,7 +23,7 @@ ragaai_catalyst/tracers/instrumentators/llamaindex.py,sha256=SMrRlR4xM7k9HK43hak
23
23
  ragaai_catalyst/tracers/instrumentators/openai.py,sha256=14R4KW9wQCR1xysLfsP_nxS7cqXrTPoD8En4MBAaZUU,379
24
24
  ragaai_catalyst/tracers/utils/__init__.py,sha256=KeMaZtYaTojilpLv65qH08QmpYclfpacDA0U3wg6Ybw,64
25
25
  ragaai_catalyst/tracers/utils/utils.py,sha256=ViygfJ7vZ7U0CTSA1lbxVloHp4NSlmfDzBRNCJuMhis,2374
26
- ragaai_catalyst-2.0.7.1.dist-info/METADATA,sha256=MdLOjU46-aocYQAOxj8QxLNxSb0hTyV8OACWSuhGdkE,11240
27
- ragaai_catalyst-2.0.7.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
28
- ragaai_catalyst-2.0.7.1.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
29
- ragaai_catalyst-2.0.7.1.dist-info/RECORD,,
26
+ ragaai_catalyst-2.0.7.2.dist-info/METADATA,sha256=-t4xrOLS05B78m-JHQanSAflEBxHDLjgYwQA80J60b0,11240
27
+ ragaai_catalyst-2.0.7.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
28
+ ragaai_catalyst-2.0.7.2.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
29
+ ragaai_catalyst-2.0.7.2.dist-info/RECORD,,