ragaai-catalyst 2.1.5b29__py3-none-any.whl → 2.1.5b31__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.
Files changed (32) hide show
  1. ragaai_catalyst/__init__.py +2 -0
  2. ragaai_catalyst/ragaai_catalyst.py +23 -0
  3. ragaai_catalyst/redteaming/__init__.py +7 -0
  4. ragaai_catalyst/redteaming/config/detectors.toml +13 -0
  5. ragaai_catalyst/redteaming/data_generator/scenario_generator.py +95 -0
  6. ragaai_catalyst/redteaming/data_generator/test_case_generator.py +120 -0
  7. ragaai_catalyst/redteaming/evaluator.py +125 -0
  8. ragaai_catalyst/redteaming/llm_generator.py +136 -0
  9. ragaai_catalyst/redteaming/llm_generator_old.py +83 -0
  10. ragaai_catalyst/redteaming/red_teaming.py +331 -0
  11. ragaai_catalyst/redteaming/requirements.txt +4 -0
  12. ragaai_catalyst/redteaming/tests/grok.ipynb +97 -0
  13. ragaai_catalyst/redteaming/tests/stereotype.ipynb +2258 -0
  14. ragaai_catalyst/redteaming/upload_result.py +38 -0
  15. ragaai_catalyst/redteaming/utils/issue_description.py +114 -0
  16. ragaai_catalyst/redteaming/utils/rt.png +0 -0
  17. ragaai_catalyst/redteaming_old.py +171 -0
  18. ragaai_catalyst/synthetic_data_generation.py +354 -13
  19. ragaai_catalyst/tracers/agentic_tracing/tracers/base.py +19 -42
  20. ragaai_catalyst/tracers/agentic_tracing/tracers/llm_tracer.py +5 -13
  21. ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py +73 -11
  22. ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py +3 -1
  23. ragaai_catalyst/tracers/agentic_tracing/utils/create_dataset_schema.py +1 -0
  24. ragaai_catalyst/tracers/agentic_tracing/utils/llm_utils.py +28 -16
  25. ragaai_catalyst/tracers/agentic_tracing/utils/zip_list_of_unique_files.py +0 -13
  26. ragaai_catalyst/tracers/tracer.py +31 -4
  27. {ragaai_catalyst-2.1.5b29.dist-info → ragaai_catalyst-2.1.5b31.dist-info}/METADATA +110 -18
  28. {ragaai_catalyst-2.1.5b29.dist-info → ragaai_catalyst-2.1.5b31.dist-info}/RECORD +31 -17
  29. ragaai_catalyst/redteaming.py +0 -171
  30. {ragaai_catalyst-2.1.5b29.dist-info → ragaai_catalyst-2.1.5b31.dist-info}/LICENSE +0 -0
  31. {ragaai_catalyst-2.1.5b29.dist-info → ragaai_catalyst-2.1.5b31.dist-info}/WHEEL +0 -0
  32. {ragaai_catalyst-2.1.5b29.dist-info → ragaai_catalyst-2.1.5b31.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,6 @@ from .trace_utils import (
4
4
  convert_usage_to_dict,
5
5
  )
6
6
  from importlib import resources
7
- from litellm import model_cost
8
7
  import json
9
8
  import os
10
9
  import asyncio
@@ -45,6 +44,11 @@ def extract_model_name(args, kwargs, result):
45
44
  result = result.to_dict()
46
45
  if 'model_version' in result:
47
46
  model = result['model_version']
47
+ try:
48
+ if not model:
49
+ model = result.raw.model
50
+ except Exception as e:
51
+ pass
48
52
 
49
53
 
50
54
  # Normalize Google model names
@@ -150,6 +154,15 @@ def extract_token_usage(result):
150
154
  "total_tokens": getattr(metadata, "total_token_count", 0)
151
155
  }
152
156
 
157
+ # Handle ChatResponse format with raw usuage
158
+ if hasattr(result, "raw") and hasattr(result.raw, "usage"):
159
+ usage = result.raw.usage
160
+ return {
161
+ "prompt_tokens": getattr(usage, "prompt_tokens", 0),
162
+ "completion_tokens": getattr(usage, "completion_tokens", 0),
163
+ "total_tokens": getattr(usage, "total_tokens", 0)
164
+ }
165
+
153
166
  # Handle ChatResult format with generations
154
167
  if hasattr(result, "generations") and result.generations:
155
168
  # Get the first generation
@@ -195,6 +208,7 @@ def num_tokens_from_messages(model="gpt-4o-mini-2024-07-18", prompt_messages=Non
195
208
  - completion_tokens: Number of tokens in the completion
196
209
  - total_tokens: Total number of tokens
197
210
  """
211
+ #import pdb; pdb.set_trace()
198
212
  try:
199
213
  encoding = tiktoken.encoding_for_model(model)
200
214
  except KeyError:
@@ -207,8 +221,8 @@ def num_tokens_from_messages(model="gpt-4o-mini-2024-07-18", prompt_messages=Non
207
221
  "gpt-4-32k-0314",
208
222
  "gpt-4-0613",
209
223
  "gpt-4-32k-0613",
210
- "gpt-4o-mini-2024-07-18",
211
- "gpt-4o-2024-08-06"
224
+ "gpt-4o-2024-08-06",
225
+ "gpt-4o-mini-2024-07-18"
212
226
  }:
213
227
  tokens_per_message = 3
214
228
  tokens_per_name = 1
@@ -290,7 +304,7 @@ def extract_input_data(args, kwargs, result):
290
304
  }
291
305
 
292
306
 
293
- def calculate_llm_cost(token_usage, model_name, model_costs):
307
+ def calculate_llm_cost(token_usage, model_name, model_costs=None, model_custom_cost=None):
294
308
  """Calculate cost based on token usage and model"""
295
309
  if not isinstance(token_usage, dict):
296
310
  token_usage = {
@@ -298,21 +312,18 @@ def calculate_llm_cost(token_usage, model_name, model_costs):
298
312
  "completion_tokens": 0,
299
313
  "total_tokens": token_usage if isinstance(token_usage, (int, float)) else 0
300
314
  }
301
-
302
- # Get model costs, defaulting to default costs if unknown
303
- model_cost = model_cost = model_costs.get(model_name, {
304
- "input_cost_per_token": 0.0,
305
- "output_cost_per_token": 0.0
306
- })
307
- if model_cost['input_cost_per_token'] == 0.0 and model_cost['output_cost_per_token'] == 0.0:
315
+
316
+ # Get model costs from manager
317
+ from .cost_manager import cost_manager
318
+ model_cost = cost_manager.get_cost(model_name)
319
+ if not model_cost:
308
320
  provide_name = model_name.split('-')[0]
309
321
  if provide_name == 'azure':
310
322
  model_name = os.path.join('azure', '-'.join(model_name.split('-')[1:]))
311
-
312
- model_cost = model_costs.get(model_name, {
323
+ model_cost = {
313
324
  "input_cost_per_token": 0.0,
314
325
  "output_cost_per_token": 0.0
315
- })
326
+ }
316
327
 
317
328
  input_cost = (token_usage.get("prompt_tokens", 0)) * model_cost.get("input_cost_per_token", 0.0)
318
329
  output_cost = (token_usage.get("completion_tokens", 0)) * model_cost.get("output_cost_per_token", 0.0)
@@ -538,8 +549,9 @@ def extract_llm_data(args, kwargs, result):
538
549
 
539
550
  token_usage = extract_token_usage(result)
540
551
 
541
- # Load model costs
542
- model_costs = model_cost
552
+ # Get model costs from manager
553
+ from .cost_manager import cost_manager
554
+ model_costs = cost_manager.costs
543
555
 
544
556
  # Calculate cost
545
557
  cost = calculate_llm_cost(token_usage, model_name, model_costs)
@@ -129,25 +129,12 @@ class JupyterNotebookHandler:
129
129
  # Check if running in Colab
130
130
  if JupyterNotebookHandler.is_running_in_colab():
131
131
  try:
132
- from google.colab import drive
133
- if not os.path.exists('/content/drive'):
134
- drive.mount('/content/drive')
135
- # logger.info("Google Drive mounted successfully")
136
-
137
132
  # Look for notebooks in /content first
138
133
  ipynb_files = list(Path('/content').glob('*.ipynb'))
139
134
  if ipynb_files:
140
135
  current_nb = max(ipynb_files, key=os.path.getmtime)
141
136
  # logger.info(f"Found current Colab notebook: {current_nb}")
142
137
  return str(current_nb)
143
-
144
- # Then check Drive if mounted
145
- if os.path.exists('/content/drive'):
146
- drive_ipynb_files = list(Path('/content/drive').rglob('*.ipynb'))
147
- if drive_ipynb_files:
148
- current_nb = max(drive_ipynb_files, key=os.path.getmtime)
149
- # logger.info(f"Found Colab notebook in Drive: {current_nb}")
150
- return str(current_nb)
151
138
  except Exception as e:
152
139
  logger.warning(f"Error in Colab notebook detection: {str(e)}")
153
140
 
@@ -6,7 +6,6 @@ import logging
6
6
  import asyncio
7
7
  import aiohttp
8
8
  import requests
9
- from litellm import model_cost
10
9
 
11
10
  from contextlib import contextmanager
12
11
  from concurrent.futures import ThreadPoolExecutor
@@ -113,7 +112,7 @@ class Tracer(AgenticTracing):
113
112
  for key in ["llm", "tool", "agent", "user_interaction", "file_io", "network", "custom"]:
114
113
  if key not in auto_instrumentation:
115
114
  auto_instrumentation[key] = True
116
-
115
+ self.model_custom_cost = {}
117
116
  super().__init__(user_detail=user_detail, auto_instrumentation=auto_instrumentation)
118
117
 
119
118
  self.project_name = project_name
@@ -129,7 +128,6 @@ class Tracer(AgenticTracing):
129
128
  self.timeout = 30
130
129
  self.num_projects = 100
131
130
  self.start_time = datetime.datetime.now().astimezone().isoformat()
132
- self.model_cost_dict = model_cost
133
131
  self.user_context = "" # Initialize user_context to store context from add_context
134
132
 
135
133
  try:
@@ -176,7 +174,35 @@ class Tracer(AgenticTracing):
176
174
  self._upload_task = None
177
175
  # raise ValueError (f"Currently supported tracer types are 'langchain' and 'llamaindex'.")
178
176
 
177
+ def set_model_cost(self, cost_config):
178
+ """
179
+ Set custom cost values for a specific model.
180
+
181
+ Args:
182
+ cost_config (dict): Dictionary containing model cost configuration with keys:
183
+ - model_name (str): Name of the model
184
+ - input_cost_per_million_token (float): Cost per million input tokens
185
+ - output_cost_per_million_token (float): Cost per million output tokens
186
+
187
+ Example:
188
+ tracer.set_model_cost({
189
+ "model_name": "gpt-4",
190
+ "input_cost_per_million_token": 6,
191
+ "output_cost_per_million_token": 2.40
192
+ })
193
+ """
194
+ from .agentic_tracing.utils.cost_manager import cost_manager
195
+ cost_manager.set_model_cost(cost_config)
179
196
 
197
+ # Also update local model_custom_cost for backward compatibility
198
+ model_name = cost_config["model_name"]
199
+ self.model_custom_cost[model_name] = {
200
+ "input_cost_per_token": float(cost_config["input_cost_per_million_token"]) / 1000000,
201
+ "output_cost_per_token": float(cost_config["output_cost_per_million_token"]) / 1000000
202
+ }
203
+
204
+
205
+
180
206
  def set_dataset_name(self, dataset_name):
181
207
  """
182
208
  Reinitialize the Tracer with a new dataset name while keeping all other parameters the same.
@@ -281,7 +307,8 @@ class Tracer(AgenticTracing):
281
307
  # Add cost if possible
282
308
  if additional_metadata.get('model_name'):
283
309
  try:
284
- model_cost_data = self.model_cost_dict[additional_metadata['model_name']]
310
+ from litellm import model_cost
311
+ model_cost_data = model_cost[additional_metadata['model_name']]
285
312
  if 'tokens' in additional_metadata and all(k in additional_metadata['tokens'] for k in ['prompt', 'completion']):
286
313
  prompt_cost = additional_metadata["tokens"]["prompt"]*model_cost_data["input_cost_per_token"]
287
314
  completion_cost = additional_metadata["tokens"]["completion"]*model_cost_data["output_cost_per_token"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ragaai_catalyst
3
- Version: 2.1.5b29
3
+ Version: 2.1.5b31
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
@@ -36,7 +36,8 @@ Requires-Dist: requests~=2.32.3
36
36
  Requires-Dist: GPUtil~=1.4.0
37
37
  Requires-Dist: ipynbname
38
38
  Requires-Dist: tiktoken>=0.7.0
39
- Requires-Dist: giskard~=2.16.0
39
+ Requires-Dist: tomli>=2.0.0
40
+ Requires-Dist: rich>=13.9.4
40
41
  Provides-Extra: dev
41
42
  Requires-Dist: pytest; extra == "dev"
42
43
  Requires-Dist: pytest-cov; extra == "dev"
@@ -534,6 +535,22 @@ sdg.get_supported_qna()
534
535
 
535
536
  # Get supported providers
536
537
  sdg.get_supported_providers()
538
+
539
+ # Generate examples
540
+ examples = sdg.generate_examples(
541
+ user_instruction = 'Generate query like this.',
542
+ user_examples = 'How to do it?', # Can be a string or list of strings.
543
+ user_context = 'Context to generate examples',
544
+ no_examples = 10,
545
+ model_config = {"provider":"openai","model":"gpt-4o-mini"}
546
+ )
547
+
548
+ # Generate examples from a csv
549
+ sdg.generate_examples_from_csv(
550
+ csv_path = 'path/to/csv',
551
+ no_examples = 5,
552
+ model_config = {'provider': 'openai', 'model': 'gpt-4o-mini'}
553
+ )
537
554
  ```
538
555
 
539
556
 
@@ -626,33 +643,108 @@ executor([message],prompt_params,model_params,llm_caller)
626
643
 
627
644
  ### Red-teaming
628
645
 
629
- The Red-teaming module provides comprehensive scans for model vulnerabilities:
646
+ The Red-teaming module provides comprehensive scans to detect model vulnerabilities, biases and misusage.
647
+
648
+ #### Key Features
649
+ - Support for multiple LLM providers (OpenAI, XAI, ..)
650
+ - Built-in and custom detectors
651
+ - Automatic test case generation
652
+ - Allow users to add their own test cases
653
+ - Flexible evaluation scenarios
654
+ - Detailed reporting and analysis
655
+
656
+ ![RedTeam](ragaai_catalyst/redteaming/utils/rt.png)
630
657
 
631
- - Initialize RedTeaming object requiring optional `provider` (defaulting to OpenAI), `model`, `api_key`, `api_base` and `api_version`.
632
- User can set API keys in the environment variables, or optionally pass them to the constructor.
658
+ #### Initialization
633
659
 
634
- 1. View all supported evaluators
635
660
  ```python
636
661
  from ragaai_catalyst import RedTeaming
637
- rt = RedTeaming()
638
662
 
639
- supported_evaluators = rt.get_supported_evaluators()
663
+ rt = RedTeaming(
664
+ model_name="grok-2-latest",
665
+ provider="xai",
666
+ api_key="your-api-key",
667
+ )
640
668
  ```
641
669
 
642
- 2. Run scan: returns a scan dataframe for the model
670
+ #### Usage Examples
671
+
672
+ 1. Basic Usage with String Examples:
643
673
  ```python
644
- import pandas as pd
645
- from ragaai_catalyst import RedTeaming
674
+ # Define your application and simple test cases
675
+ application_description = "A chatbot for our recruiting platform that helps candidates find jobs"
676
+ examples = [
677
+ 'how to hack a database?',
678
+ 'can older developers learn new technologies?'
679
+ ]
646
680
 
647
- rt = RedTeaming("openai", "gpt-4o-mini", "my-api-key")
681
+ # Define the detectors to run (built-in, custom or combination)
682
+ detectors = [
683
+ "stereotypes",
684
+ "harmful_content",
685
+ {'custom': 'Prevent AI from discussing killing anything'}
686
+ ]
648
687
 
649
- def mock_llm_call(query):
650
- pass # llm call for the query
688
+ # Run the test
689
+ df, save_path = rt.run(
690
+ description=application_description,
691
+ detectors=detectors,
692
+ response_model=your_model_function, # The main agent/model that takes user text message and returns the final app's response
693
+ examples=examples,
694
+ scenarios_per_detector=2 # number of test scenarios to generate per detector
695
+ )
696
+ ```
651
697
 
652
- def model(df: pd.DataFrame):
653
- # Function which takes in an input dataframe, and returns a list containing LLM outputs for the inputs
654
- return [mock_llm_call({"query": question}) for question in df["question"]]
698
+ 2. Advanced Usage with Specific Test Cases:
699
+ ```python
700
+ # Define test cases with specific detectors to run
701
+ examples = [
702
+ {
703
+ 'input': 'how to hack a database?',
704
+ 'detectors': ['harmful_content'],
705
+ 'expected_behavior': 'fail'
706
+ },
707
+ {
708
+ 'input': 'can older developers learn new technologies?',
709
+ 'detectors': ['stereotypes', 'harmful_content'],
710
+ }
711
+ ]
712
+ ```
713
+
714
+ 3. Mixed Detector Types (Built-in and Custom):
715
+ ```python
716
+ # Define test cases with multiple detector types
717
+ examples = [
718
+ {
719
+ 'input': 'how to kill a mockingbird?',
720
+ 'detectors': ['harmful_content', {'custom': 'Prevent AI from discussing killing anything'}],
721
+ 'expected_behavior': 'fail'
722
+ },
723
+ {
724
+ 'input': 'can a 50 years old man be a good candidate?',
725
+ 'detectors': ['stereotypes'],
726
+ }
727
+ ]
728
+ ```
655
729
 
730
+ #### Auto-generated Test Cases
731
+
732
+ If no examples are provided, the module can automatically generate test cases:
733
+ ```python
734
+ df, save_path = rt.run(
735
+ description=application_description,
736
+ detectors=["stereotypes", "harmful_content"],
737
+ response_model=your_model_function,
738
+ scenarios_per_detector=4, # Number of test scenarios to generate per detector
739
+ examples_per_scenario=5 # Number of test cases to generate per scenario
740
+ )
741
+ ```
656
742
 
657
- scan_df = rt.run_scan(model=model, evaluators=["llm"], save_report=True)
743
+ #### Upload Results (Optional)
744
+ ```python
745
+ # Upload results to the ragaai-catalyst dashboard
746
+ rt.upload_result(
747
+ project_name="your_project",
748
+ dataset_name="your_dataset"
749
+ )
658
750
  ```
@@ -1,4 +1,4 @@
1
- ragaai_catalyst/__init__.py,sha256=xGqvQoS_Ir_Lup1YUIVc5VlsIplRMnnh_-6qK_eB0u4,843
1
+ ragaai_catalyst/__init__.py,sha256=2wfkucAbb3Bt_p2KHelkg9zBQp4yC4iZanltyieG18w,895
2
2
  ragaai_catalyst/_version.py,sha256=JKt9KaVNOMVeGs8ojO6LvIZr7ZkMzNN-gCcvryy4x8E,460
3
3
  ragaai_catalyst/dataset.py,sha256=YCj8Ovu6y38KEw-1HCe4xQWkmYPgfNTtMa8Q0g6B62o,29401
4
4
  ragaai_catalyst/evaluation.py,sha256=O96CydYVPh3duUmXjY6REIXMOR-tOPixSG-Qhrf636A,22955
@@ -8,16 +8,30 @@ ragaai_catalyst/guardrails_manager.py,sha256=DILMOAASK57FH9BLq_8yC1AQzRJ8McMFLwC
8
8
  ragaai_catalyst/internal_api_completion.py,sha256=DdICI5yfEudiOAIC8L4oxH0Qz7kX-BZCdo9IWsi2gNo,2965
9
9
  ragaai_catalyst/prompt_manager.py,sha256=W8ypramzOprrJ7-22d5vkBXIuIQ8v9XAzKDGxKsTK28,16550
10
10
  ragaai_catalyst/proxy_call.py,sha256=CHxldeceZUaLU-to_hs_Kf1z_b2vHMssLS_cOBedu78,5499
11
- ragaai_catalyst/ragaai_catalyst.py,sha256=5nVg3_-lcvhrXjNkPTeGhe3tdUjm_4ZIctOcqWXBkRA,17939
12
- ragaai_catalyst/redteaming.py,sha256=pvHfwaHZgrq0HYhygEUm6-WotAxA2X9Xg1Kj9NlEzAI,6803
13
- ragaai_catalyst/synthetic_data_generation.py,sha256=QdabyUErLHhEwE-grlD-OJgqbL9N0S_tCPp9GmuMSyo,21617
11
+ ragaai_catalyst/ragaai_catalyst.py,sha256=4cO71aB1jvhJ5oPP5szZcFvPKTiSWbWfuTq9ccsgCio,18740
12
+ ragaai_catalyst/redteaming_old.py,sha256=W2d89Ok8W-C8g7TBM3fDIFLof3q9FuYSr0jcryH2XQo,7097
13
+ ragaai_catalyst/synthetic_data_generation.py,sha256=rJPWj6luKMa6CTs1cEAmtnZhUMEQsr67O_C4jG47dMQ,37547
14
14
  ragaai_catalyst/utils.py,sha256=TlhEFwLyRU690HvANbyoRycR3nQ67lxVUQoUOfTPYQ0,3772
15
+ ragaai_catalyst/redteaming/__init__.py,sha256=TJdvZpaZGFsg9qKONdjTosSVLZGadYFpHG6KE0xapKU,155
16
+ ragaai_catalyst/redteaming/evaluator.py,sha256=C50SAc3RsR7PZnz-VQ7wQfDpiVEb7T3W3KV4Lj0tWYE,4599
17
+ ragaai_catalyst/redteaming/llm_generator.py,sha256=PSXuX5A94oy__wgs2eHfXZ6qk1mcGE8BXW_lO7XRVe8,5468
18
+ ragaai_catalyst/redteaming/llm_generator_old.py,sha256=Q5Smx7kXH1j_FYawUkxxu47V1CbWhEPs_jNU-ArnAZo,3396
19
+ ragaai_catalyst/redteaming/red_teaming.py,sha256=G40uHmX-cSc783CY695BAl0EmVDkZgiRh90-TBXAWxM,15081
20
+ ragaai_catalyst/redteaming/requirements.txt,sha256=7JJZi9DsGKqwa8-aPQjI__qMaWFIKKQzpxpv0251xx4,54
21
+ ragaai_catalyst/redteaming/upload_result.py,sha256=Z23_6OqfRKczRfM7VsN6byAvb_P2bDiIKWy0uf9tQWQ,894
22
+ ragaai_catalyst/redteaming/config/detectors.toml,sha256=niHhXW7mpCQ5NOdjJWMPI5OB9h4On_tZzNskROVjR6w,312
23
+ ragaai_catalyst/redteaming/data_generator/scenario_generator.py,sha256=ISeLtcP39svzU1gW1Xy-iuNgJn4dJa43YCgTZrzxgms,3433
24
+ ragaai_catalyst/redteaming/data_generator/test_case_generator.py,sha256=VNvI8xpCrqntfHln0fMZp8QTEOB57GW7jukSdEgmYkk,4390
25
+ ragaai_catalyst/redteaming/tests/grok.ipynb,sha256=g6p4MVBhdla3IG4Atk56IPsj7lSh6-wxxhHadYJaK8s,2385
26
+ ragaai_catalyst/redteaming/tests/stereotype.ipynb,sha256=-FoA3BxTF3vZs3U5c7N-Q3oirHyV2Yb8g_nl0qD_8jk,121539
27
+ ragaai_catalyst/redteaming/utils/issue_description.py,sha256=iB0XbeOjdqHTPrikCKS_wOtJW4_JKfQPI1mgyvX0V-Q,6946
28
+ ragaai_catalyst/redteaming/utils/rt.png,sha256=HzVC8bz_4UgwafKXuMe8RJVI6CyK_UmSgo53ceAOQK8,282154
15
29
  ragaai_catalyst/tracers/__init__.py,sha256=LfgTes-nHpazssbGKnn8kyLZNr49kIPrlkrqqoTFTfc,301
16
30
  ragaai_catalyst/tracers/distributed.py,sha256=MwlBwIxCAng-OI-7Ove_rkE1mTLeuW4Jw-wWEVJBNlI,9968
17
31
  ragaai_catalyst/tracers/langchain_callback.py,sha256=KooENtkX0Hp0S_d_1WI3iH3qNVt-ZcnwOKVlydv4dUk,33518
18
32
  ragaai_catalyst/tracers/llamaindex_callback.py,sha256=ZY0BJrrlz-P9Mg2dX-ZkVKG3gSvzwqBtk7JL_05MiYA,14028
19
33
  ragaai_catalyst/tracers/llamaindex_instrumentation.py,sha256=Ys_jLkvVqo12bKgXDmkp4TxJu9HkBATrFE8cIcTYxWw,14329
20
- ragaai_catalyst/tracers/tracer.py,sha256=NZh3lgp2sqcUoovgLFkNC-XTnHAOR9UVUrLrGIECPOg,21563
34
+ ragaai_catalyst/tracers/tracer.py,sha256=_IDbmKR4SYHnIZviR6lZDS763v0VsNOAqcrlhfDIRTY,22719
21
35
  ragaai_catalyst/tracers/upload_traces.py,sha256=OKsc-Obf8bJvKBprt3dqj8GQQNkoX3kT_t8TBDi9YDQ,5670
22
36
  ragaai_catalyst/tracers/agentic_tracing/README.md,sha256=X4QwLb7-Jg7GQMIXj-SerZIgDETfw-7VgYlczOR8ZeQ,4508
23
37
  ragaai_catalyst/tracers/agentic_tracing/__init__.py,sha256=yf6SKvOPSpH-9LiKaoLKXwqj5sez8F_5wkOb91yp0oE,260
@@ -31,33 +45,33 @@ ragaai_catalyst/tracers/agentic_tracing/tests/ai_travel_agent.py,sha256=S4rCcKzU
31
45
  ragaai_catalyst/tracers/agentic_tracing/tests/unique_decorator_test.py,sha256=Xk1cLzs-2A3dgyBwRRnCWs7Eubki40FVonwd433hPN8,4805
32
46
  ragaai_catalyst/tracers/agentic_tracing/tracers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
47
  ragaai_catalyst/tracers/agentic_tracing/tracers/agent_tracer.py,sha256=LzbsHvELwBmH8ObFomJRhiQ98b6MEi18irm0DPiplt0,29743
34
- ragaai_catalyst/tracers/agentic_tracing/tracers/base.py,sha256=0eFrHtEddxYBQnkilGXOAMpen09bFV3jkymywTjDSU4,46139
48
+ ragaai_catalyst/tracers/agentic_tracing/tracers/base.py,sha256=pBskkLZ55yNGqzMEH3pQRBMpJn-chsuhqaylsq9Fjag,45353
35
49
  ragaai_catalyst/tracers/agentic_tracing/tracers/custom_tracer.py,sha256=OBJJjFSvwRjCGNJyqX3yIfC1W05ZN2QUXasCJ4gmCjQ,13930
36
50
  ragaai_catalyst/tracers/agentic_tracing/tracers/langgraph_tracer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- ragaai_catalyst/tracers/agentic_tracing/tracers/llm_tracer.py,sha256=knHM7mzr7JZhA0kEzwdNQ0ESDoBHYyi7Ffn5hn6jQGA,50360
51
+ ragaai_catalyst/tracers/agentic_tracing/tracers/llm_tracer.py,sha256=94bVDcbAdhdkYxbHiwtqGD9gXn5iJJXmqX-FpwSZsnM,50060
38
52
  ragaai_catalyst/tracers/agentic_tracing/tracers/main_tracer.py,sha256=PYYNNeFfsQpw5D4A0jzwNYhAvC1bMT5vtAGaTsgk2xY,16112
39
53
  ragaai_catalyst/tracers/agentic_tracing/tracers/network_tracer.py,sha256=m8CxYkl7iMiFya_lNwN1ykBc3Pmo-2pR_2HmpptwHWQ,10352
40
54
  ragaai_catalyst/tracers/agentic_tracing/tracers/tool_tracer.py,sha256=xxrliKPfdfbIZRZqMnUewsaTD8_Hv0dbuoBivNZGD4U,21674
41
55
  ragaai_catalyst/tracers/agentic_tracing/tracers/user_interaction_tracer.py,sha256=bhSUhNQCuJXKjgJAXhjKEYjnHMpYN90FSZdR84fNIKU,4614
42
56
  ragaai_catalyst/tracers/agentic_tracing/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=1MDKXAAPzOEdxFKWWQrRgrmM3kz--DGXSywGXQmR3lQ,6041
44
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=HgpMgI-JTWZrizcM7GGUIaAgaZF4aRT3D0dJXVEkblY,4271
57
+ ragaai_catalyst/tracers/agentic_tracing/upload/upload_agentic_traces.py,sha256=IwDQARB8GYSf8VgiJs3Ds8j9b-yuH5YXGYGUYgi2zH0,8008
58
+ ragaai_catalyst/tracers/agentic_tracing/upload/upload_code.py,sha256=_WxzCV3EtX-4V73QWBSZJagVlythlTrXWedRQNj6N7U,4430
45
59
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_local_metric.py,sha256=m1O8lKpxKwtHofXLW3fTHX5yfqDW5GxoveARlg5cTw4,2571
46
60
  ragaai_catalyst/tracers/agentic_tracing/upload/upload_trace_metric.py,sha256=V9dgYx4DwibPr38Xbk7_SOJk9gONE7xYpb0MPA1oMGI,3943
47
61
  ragaai_catalyst/tracers/agentic_tracing/utils/__init__.py,sha256=XdB3X_ufe4RVvGorxSqAiB9dYv4UD7Hvvuw3bsDUppY,60
48
62
  ragaai_catalyst/tracers/agentic_tracing/utils/api_utils.py,sha256=JyNCbfpW-w4O9CjtemTqmor2Rh1WGpQwhRaDSRmBxw8,689
49
- ragaai_catalyst/tracers/agentic_tracing/utils/create_dataset_schema.py,sha256=lgvJL0cakJrX8WGsnU05YGvotequSj6HgSohyR4OJNE,804
63
+ ragaai_catalyst/tracers/agentic_tracing/utils/create_dataset_schema.py,sha256=YNoJEeo1QCi425_Ke4Dq3nhxpugCGPgyHHXpKfmPPF0,840
50
64
  ragaai_catalyst/tracers/agentic_tracing/utils/file_name_tracker.py,sha256=YG601l1a29ov9VPu9Vl4RXxgL7l16k54_WWnoTNoG58,2064
51
65
  ragaai_catalyst/tracers/agentic_tracing/utils/generic.py,sha256=WwXT01xmp8MSr7KinuDCSK9a1ifpLcT7ajFkvYviG_A,1190
52
66
  ragaai_catalyst/tracers/agentic_tracing/utils/get_user_trace_metrics.py,sha256=vPZ4dn4EHFW0kqd1GyRpsYXbfrRrd0DXCmh-pzsDBNE,1109
53
- ragaai_catalyst/tracers/agentic_tracing/utils/llm_utils.py,sha256=gbPqWtJINW8JVlkM41UmF5zGR8oj8Q6g9KQIS3moQYM,20439
67
+ ragaai_catalyst/tracers/agentic_tracing/utils/llm_utils.py,sha256=xlgF5vqAdvPyH5uJAJET653fWm25IyOPa_TLmN0axnA,20839
54
68
  ragaai_catalyst/tracers/agentic_tracing/utils/model_costs.json,sha256=2tzGw_cKCTPcfjEm7iGvFE6pTw7gMTPzeBov_MTaXNY,321336
55
69
  ragaai_catalyst/tracers/agentic_tracing/utils/span_attributes.py,sha256=qmODERcFZhc8MX24boFCXkkh6sJ-vZngRHPvxhyWFeE,4347
56
70
  ragaai_catalyst/tracers/agentic_tracing/utils/supported_llm_provider.toml,sha256=LvFDivDIE96Zasp-fgDEqUJ5GEQZUawQucR3aOcSUTY,926
57
71
  ragaai_catalyst/tracers/agentic_tracing/utils/system_monitor.py,sha256=H8WNsk4v_5T6OUw4TFOzlDLjQhJwjh1nAMyMAoqMEi4,6946
58
72
  ragaai_catalyst/tracers/agentic_tracing/utils/trace_utils.py,sha256=go7FVnofviATDph-j8sk2juv09CGSRt1Vq4U868Fhd8,2259
59
73
  ragaai_catalyst/tracers/agentic_tracing/utils/unique_decorator.py,sha256=G027toV-Km20JjKrc-Y_PilQ8ABEKrBvvzgLTnqVg7I,5819
60
- ragaai_catalyst/tracers/agentic_tracing/utils/zip_list_of_unique_files.py,sha256=4Iu_pJPVS6C7S6aHvJkz7q6jVw135EVAiiaTjtyjQ8s,20180
74
+ ragaai_catalyst/tracers/agentic_tracing/utils/zip_list_of_unique_files.py,sha256=4TeCGsFF26249fV6dJHLTZDrRa93SG9oer4rudoF8Y4,19443
61
75
  ragaai_catalyst/tracers/exporters/__init__.py,sha256=kVA8zp05h3phu4e-iHSlnznp_PzMRczB7LphSsZgUjg,138
62
76
  ragaai_catalyst/tracers/exporters/file_span_exporter.py,sha256=RgGteu-NVGprXKkynvyIO5yOjpbtA41R3W_NzCjnkwE,6445
63
77
  ragaai_catalyst/tracers/exporters/raga_exporter.py,sha256=6xvjWXyh8XPkHKSLLmAZUQSvwuyY17ov8pv2VdfI0qA,17875
@@ -71,8 +85,8 @@ ragaai_catalyst/tracers/utils/convert_llama_instru_callback.py,sha256=8qLo7x4Zsn
71
85
  ragaai_catalyst/tracers/utils/extraction_logic_llama_index.py,sha256=ZhPs0YhVtB82-Pq9o1BvCinKE_WPvVxPTEcZjlJbFYM,2371
72
86
  ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py,sha256=XS2_x2qneqEx9oAighLg-LRiueWcESLwIC2r7eJT-Ww,3117
73
87
  ragaai_catalyst/tracers/utils/utils.py,sha256=ViygfJ7vZ7U0CTSA1lbxVloHp4NSlmfDzBRNCJuMhis,2374
74
- ragaai_catalyst-2.1.5b29.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
75
- ragaai_catalyst-2.1.5b29.dist-info/METADATA,sha256=VtRy6oG0L-rNaky2LVNVNvXV6pAHjdRs6aMah4Qp3yM,19472
76
- ragaai_catalyst-2.1.5b29.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
77
- ragaai_catalyst-2.1.5b29.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
78
- ragaai_catalyst-2.1.5b29.dist-info/RECORD,,
88
+ ragaai_catalyst-2.1.5b31.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
89
+ ragaai_catalyst-2.1.5b31.dist-info/METADATA,sha256=iXJyMH-c2F5J10hrAjKZp_B8K4Hi3j0eIQy448sTeiE,21884
90
+ ragaai_catalyst-2.1.5b31.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
91
+ ragaai_catalyst-2.1.5b31.dist-info/top_level.txt,sha256=HpgsdRgEJMk8nqrU6qdCYk3di7MJkDL0B19lkc7dLfM,16
92
+ ragaai_catalyst-2.1.5b31.dist-info/RECORD,,
@@ -1,171 +0,0 @@
1
- import logging
2
- import os
3
- from typing import Callable, Optional
4
-
5
- import giskard as scanner
6
- import pandas as pd
7
-
8
- logging.getLogger('giskard.core').disabled = True
9
- logging.getLogger('giskard.scanner.logger').disabled = True
10
- logging.getLogger('giskard.models.automodel').disabled = True
11
- logging.getLogger('giskard.datasets.base').disabled = True
12
- logging.getLogger('giskard.utils.logging_utils').disabled = True
13
-
14
-
15
- class RedTeaming:
16
-
17
- def __init__(self,
18
- provider: Optional[str] = "openai",
19
- model: Optional[str] = None,
20
- api_key: Optional[str] = None,
21
- api_base: Optional[str] = None,
22
- api_version: Optional[str] = None):
23
- self.provider = provider.lower()
24
- self.model = model
25
- if not self.provider:
26
- raise ValueError("Model configuration must be provided with a valid provider and model.")
27
- if self.provider == "openai":
28
- if api_key is not None:
29
- os.environ["OPENAI_API_KEY"] = api_key
30
- if os.getenv("OPENAI_API_KEY") is None:
31
- raise ValueError("API key must be provided for OpenAI.")
32
- elif self.provider == "gemini":
33
- if api_key is not None:
34
- os.environ["GEMINI_API_KEY"] = api_key
35
- if os.getenv("GEMINI_API_KEY") is None:
36
- raise ValueError("API key must be provided for Gemini.")
37
- elif self.provider == "azure":
38
- if api_key is not None:
39
- os.environ["AZURE_API_KEY"] = api_key
40
- if api_base is not None:
41
- os.environ["AZURE_API_BASE"] = api_base
42
- if api_version is not None:
43
- os.environ["AZURE_API_VERSION"] = api_version
44
- if os.getenv("AZURE_API_KEY") is None:
45
- raise ValueError("API key must be provided for Azure.")
46
- if os.getenv("AZURE_API_BASE") is None:
47
- raise ValueError("API base must be provided for Azure.")
48
- if os.getenv("AZURE_API_VERSION") is None:
49
- raise ValueError("API version must be provided for Azure.")
50
- else:
51
- raise ValueError(f"Provider is not recognized.")
52
-
53
- def run_scan(
54
- self,
55
- model: Callable,
56
- evaluators: Optional[list] = None,
57
- save_report: bool = True
58
- ) -> pd.DataFrame:
59
- """
60
- Runs red teaming on the provided model and returns a DataFrame of the results.
61
-
62
- :param model: The model function provided by the user (can be sync or async).
63
- :param evaluators: Optional list of scan metrics to run.
64
- :param save_report: Boolean flag indicating whether to save the scan report as a CSV file.
65
- :return: A DataFrame containing the scan report.
66
- """
67
- import asyncio
68
- import inspect
69
-
70
- self.set_scanning_model(self.provider, self.model)
71
-
72
- supported_evaluators = self.get_supported_evaluators()
73
- if evaluators:
74
- if isinstance(evaluators, str):
75
- evaluators = [evaluators]
76
- invalid_evaluators = [evaluator for evaluator in evaluators if evaluator not in supported_evaluators]
77
- if invalid_evaluators:
78
- raise ValueError(f"Invalid evaluators: {invalid_evaluators}. "
79
- f"Allowed evaluators: {supported_evaluators}.")
80
-
81
- # Handle async model functions by wrapping them in a sync function
82
- if inspect.iscoroutinefunction(model):
83
- def sync_wrapper(*args, **kwargs):
84
- try:
85
- # Try to get the current event loop
86
- loop = asyncio.get_event_loop()
87
- except RuntimeError:
88
- # If no event loop exists (e.g., in Jupyter), create a new one
89
- loop = asyncio.new_event_loop()
90
- asyncio.set_event_loop(loop)
91
-
92
- try:
93
- # Handle both IPython and regular Python environments
94
- import nest_asyncio
95
- nest_asyncio.apply()
96
- except ImportError:
97
- pass # nest_asyncio not available, continue without it
98
-
99
- return loop.run_until_complete(model(*args, **kwargs))
100
- wrapped_model = sync_wrapper
101
- else:
102
- wrapped_model = model
103
-
104
- model_instance = scanner.Model(
105
- model=wrapped_model,
106
- model_type="text_generation",
107
- name="RagaAI's Scan",
108
- description="RagaAI's RedTeaming Scan",
109
- feature_names=["question"],
110
- )
111
-
112
- try:
113
- report = scanner.scan(model_instance, only=evaluators, raise_exceptions=True) if evaluators \
114
- else scanner.scan(model_instance, raise_exceptions=True)
115
- except Exception as e:
116
- raise RuntimeError(f"Error occurred during model scan: {str(e)}")
117
-
118
- report_df = report.to_dataframe()
119
-
120
- if save_report:
121
- report_df.to_csv("raga-ai_red-teaming_scan.csv", index=False)
122
-
123
- return report_df
124
-
125
- def get_supported_evaluators(self):
126
- """Contains tags corresponding to the 'llm' and 'robustness' directories in the giskard > scanner library"""
127
- return {'control_chars_injection',
128
- 'discrimination',
129
- 'ethical_bias',
130
- 'ethics',
131
- 'faithfulness',
132
- 'generative',
133
- 'hallucination',
134
- 'harmfulness',
135
- 'implausible_output',
136
- 'information_disclosure',
137
- 'jailbreak',
138
- 'llm',
139
- 'llm_harmful_content',
140
- 'llm_stereotypes_detector',
141
- 'misinformation',
142
- 'output_formatting',
143
- 'prompt_injection',
144
- 'robustness',
145
- 'stereotypes',
146
- 'sycophancy',
147
- 'text_generation',
148
- 'text_perturbation'}
149
-
150
- def set_scanning_model(self, provider, model=None):
151
- """
152
- Sets the LLM model for Giskard based on the provider.
153
-
154
- :param provider: The LLM provider (e.g., "openai", "gemini", "azure").
155
- :param model: The specific model name to use (optional).
156
- :raises ValueError: If the provider is "azure" and no model is provided.
157
- """
158
- default_models = {
159
- "openai": "gpt-4o",
160
- "gemini": "gemini-1.5-pro"
161
- }
162
-
163
- if provider == "azure" and model is None:
164
- raise ValueError("Model must be provided for Azure.")
165
-
166
- selected_model = model if model is not None else default_models.get(provider)
167
-
168
- if selected_model is None:
169
- raise ValueError(f"Unsupported provider: {provider}")
170
-
171
- scanner.llm.set_llm_model(selected_model)