enkryptai-sdk 1.0.14__py3-none-any.whl → 1.0.16__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.
@@ -243,6 +243,19 @@ class SystemPromptDetector(BaseDTO):
243
243
  }
244
244
 
245
245
 
246
+ class GuardrailDetectorsEnum(str, Enum):
247
+ TOPIC_DETECTOR = "topic_detector"
248
+ NSFW = "nsfw"
249
+ TOXICITY = "toxicity"
250
+ PII = "pii"
251
+ INJECTION_ATTACK = "injection_attack"
252
+ KEYWORD_DETECTOR = "keyword_detector"
253
+ POLICY_VIOLATION = "policy_violation"
254
+ BIAS = "bias"
255
+ COPYRIGHT_IP = "copyright_ip"
256
+ SYSTEM_PROMPT = "system_prompt"
257
+
258
+
246
259
  @dataclass
247
260
  class GuardrailDetectors(BaseDTO):
248
261
  topic_detector: TopicDetector = field(default_factory=TopicDetector)
@@ -40,6 +40,7 @@ class ModelProviders(str, Enum):
40
40
  CUSTOM = "custom"
41
41
  HR = "hr"
42
42
  URL = "url"
43
+ ENKRYPTAI = "enkryptai"
43
44
 
44
45
 
45
46
  @dataclass
@@ -92,10 +93,11 @@ class ModelDetailConfig:
92
93
  # model_provider: str = "openai"
93
94
  model_provider: ModelProviders = ModelProviders.OPENAI
94
95
  system_prompt: str = ""
95
-
96
- endpoint_url: str = "https://api.openai.com/v1/chat/completions"
96
+ endpoint_url: str = ""
97
97
  auth_data: AuthData = field(default_factory=AuthData)
98
+ metadata: Dict[str, Any] = field(default_factory=dict)
98
99
  api_keys: Set[Optional[str]] = field(default_factory=lambda: {None})
100
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
99
101
 
100
102
 
101
103
  @dataclass
@@ -159,7 +161,7 @@ class ModelConfigDetails(BaseDTO):
159
161
  headers: str = ""
160
162
  system_prompt: str = ""
161
163
  hosting_type: str = "External"
162
- endpoint_url: str = "https://api.openai.com/v1/chat/completions"
164
+ endpoint_url: str = ""
163
165
  model_name: Optional[str] = ""
164
166
  apikey: Optional[str] = None
165
167
  paths: Optional[PathsConfig] = None
@@ -5,6 +5,19 @@ from typing import Dict, List, Optional, Any
5
5
  from dataclasses import dataclass, field, asdict
6
6
  from .datasets import DatasetConfig
7
7
  from .models import ModelConfig
8
+ from .guardrails import GuardrailDetectors
9
+
10
+ # The risk mitigation do not support all detectors, so we need to create a separate enum for them.
11
+ class RiskGuardrailDetectorsEnum(str, Enum):
12
+ NSFW = "nsfw"
13
+ TOXICITY = "toxicity"
14
+ INJECTION_ATTACK = "injection_attack"
15
+ POLICY_VIOLATION = "policy_violation"
16
+ BIAS = "bias"
17
+ # Topic, Keyword, PII are not supported by Risk Mitigation
18
+ # Below are not yet supported by Guardrails. So, also not supported by Risk Mitigation.
19
+ # COPYRIGHT_IP = "copyright_ip"
20
+ # SYSTEM_PROMPT = "system_prompt"
8
21
 
9
22
 
10
23
  @dataclass
@@ -49,13 +62,59 @@ class RedTeamTaskStatus(BaseDTO):
49
62
  status: Optional[str] = None
50
63
 
51
64
 
65
+ @dataclass
66
+ class RedTeamTaskDetailsModelConfig(BaseDTO):
67
+ system_prompt: Optional[str] = None
68
+ model_version: Optional[str] = None
69
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
70
+
71
+ @classmethod
72
+ def from_dict(cls, data: Dict) -> "RedTeamTaskDetailsModelConfig":
73
+ return cls(
74
+ system_prompt=data.get("system_prompt"),
75
+ model_version=data.get("model_version"),
76
+ )
77
+
78
+ def to_dict(self) -> Dict:
79
+ return {
80
+ "system_prompt": self.system_prompt,
81
+ "model_version": self.model_version,
82
+ }
83
+
84
+
52
85
  @dataclass
53
86
  class RedTeamTaskDetails(BaseDTO):
54
87
  created_at: Optional[str] = None
88
+ model_saved_name: Optional[str] = None
55
89
  model_name: Optional[str] = None
56
90
  status: Optional[str] = None
57
91
  test_name: Optional[str] = None
58
92
  task_id: Optional[str] = None
93
+ model_config: Optional[RedTeamTaskDetailsModelConfig] = None
94
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
95
+
96
+ @classmethod
97
+ def from_dict(cls, data: Dict) -> "RedTeamTaskDetails":
98
+ return cls(
99
+ created_at=data.get("created_at"),
100
+ model_saved_name=data.get("model_saved_name"),
101
+ model_name=data.get("model_name"),
102
+ status=data.get("status"),
103
+ test_name=data.get("test_name"),
104
+ task_id=data.get("task_id"),
105
+ model_config=RedTeamTaskDetailsModelConfig.from_dict(data.get("model_config", {})),
106
+ )
107
+
108
+ def to_dict(self) -> Dict:
109
+ return {
110
+ "created_at": self.created_at,
111
+ "model_saved_name": self.model_saved_name,
112
+ "model_name": self.model_name,
113
+ "status": self.status,
114
+ "test_name": self.test_name,
115
+ "task_id": self.task_id,
116
+ "model_config": self.model_config.to_dict(),
117
+ }
59
118
 
60
119
 
61
120
  @dataclass
@@ -114,6 +173,7 @@ class ResultSummary(BaseDTO):
114
173
  scenario: Dict[str, StatisticItem]
115
174
  category: Dict[str, StatisticItemWithTestType]
116
175
  attack_method: Dict[str, StatisticItem]
176
+ custom_test_category_risks: Dict[str, StatisticItem] = field(default_factory=dict)
117
177
  _extra_fields: Dict[str, Any] = field(default_factory=dict)
118
178
 
119
179
  @classmethod
@@ -146,6 +206,9 @@ class ResultSummary(BaseDTO):
146
206
  scenario=convert_stat_list(data.get("scenario", [])),
147
207
  category=convert_stat_test_type_list(data.get("category", [])),
148
208
  attack_method=convert_stat_list(data.get("attack_method", [])),
209
+ custom_test_category_risks=convert_stat_list(
210
+ data.get("custom_test_category_risks", [])
211
+ ),
149
212
  )
150
213
 
151
214
  def to_dict(self) -> Dict:
@@ -162,6 +225,9 @@ class ResultSummary(BaseDTO):
162
225
  d["scenario"] = convert_stat_dict(self.scenario)
163
226
  d["category"] = convert_stat_test_type_dict(self.category)
164
227
  d["attack_method"] = convert_stat_dict(self.attack_method)
228
+ d["custom_test_category_risks"] = convert_stat_dict(
229
+ self.custom_test_category_risks
230
+ )
165
231
  return d
166
232
 
167
233
 
@@ -578,6 +644,118 @@ class RedTeamTaskList(BaseDTO):
578
644
  def to_dataframe(self) -> pd.DataFrame:
579
645
  data = [task for task in self.tasks]
580
646
  return pd.DataFrame(data)
647
+
648
+
649
+ @dataclass
650
+ class RedTeamRiskMitigationGuardrailsPolicyConfig(BaseDTO):
651
+ # required_detectors: List[RiskGuardrailDetectorsEnum] = field(default_factory=list)
652
+ redteam_summary: ResultSummary = field(default_factory=ResultSummary)
653
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
654
+
655
+ @classmethod
656
+ def from_dict(cls, data: dict):
657
+ data = data.copy()
658
+ summary = ResultSummary.from_dict(data.pop("redteam_summary", {}))
659
+ return cls(
660
+ # required_detectors=[RiskGuardrailDetectorsEnum(detector) for detector in data.get("required_detectors", [])],
661
+ redteam_summary=summary,
662
+ _extra_fields=data,
663
+ )
664
+
665
+ def to_dict(self) -> dict:
666
+ return {
667
+ # "required_detectors": [detector.value for detector in self.required_detectors],
668
+ "redteam_summary": self.redteam_summary.to_dict(),
669
+ }
670
+
671
+
672
+ @dataclass
673
+ class RedTeamRiskMitigationGuardrailsPolicyResponse(BaseDTO):
674
+ analysis: str = ""
675
+ guardrails_policy: GuardrailDetectors = field(default_factory=GuardrailDetectors)
676
+ message: str = ""
677
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
678
+
679
+ @classmethod
680
+ def from_dict(cls, data: dict):
681
+ policy_data = data.get("guardrails_policy", {})
682
+
683
+ return cls(
684
+ analysis=data.get("analysis", ""),
685
+ guardrails_policy=GuardrailDetectors.from_dict(policy_data),
686
+ message=data.get("message", ""),
687
+ )
688
+
689
+ def to_dict(self) -> dict:
690
+ policy_dict = self.guardrails_policy.to_dict()
691
+
692
+ # Remove detector entries that are disabled and have no other config
693
+ final_policy_dict = {}
694
+ for key, value in policy_dict.items():
695
+ if isinstance(value, dict):
696
+ # Check if 'enabled' is the only key and its value is False
697
+ if list(value.keys()) == ['enabled'] and not value['enabled']:
698
+ continue
699
+ # Check for empty detectors that only have 'enabled': False
700
+ if not value.get("enabled", True) and len(value) == 1:
701
+ continue
702
+ # check for other empty values
703
+ if not any(v for k, v in value.items() if k != 'enabled'):
704
+ if not value.get('enabled'):
705
+ continue
706
+ final_policy_dict[key] = value
707
+
708
+ return {
709
+ "analysis": self.analysis,
710
+ "guardrails_policy": final_policy_dict,
711
+ "message": self.message,
712
+ }
713
+
714
+
715
+ @dataclass
716
+ class RedTeamRiskMitigationSystemPromptConfig(BaseDTO):
717
+ system_prompt: str = "You are a helpful AI Assistant"
718
+ redteam_summary: ResultSummary = field(default_factory=ResultSummary)
719
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
720
+
721
+ @classmethod
722
+ def from_dict(cls, data: dict):
723
+ data = data.copy()
724
+ summary = ResultSummary.from_dict(data.pop("redteam_summary", {}))
725
+ return cls(
726
+ system_prompt=data.get("system_prompt", ""),
727
+ redteam_summary=summary,
728
+ _extra_fields=data,
729
+ )
730
+
731
+ def to_dict(self) -> dict:
732
+ return {
733
+ "system_prompt": self.system_prompt,
734
+ "redteam_summary": self.redteam_summary.to_dict(),
735
+ }
736
+
737
+
738
+ @dataclass
739
+ class RedTeamRiskMitigationSystemPromptResponse(BaseDTO):
740
+ analysis: str = ""
741
+ system_prompt: str = ""
742
+ message: str = ""
743
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
744
+
745
+ @classmethod
746
+ def from_dict(cls, data: dict):
747
+ return cls(
748
+ analysis=data.get("analysis", ""),
749
+ system_prompt=data.get("system_prompt", ""),
750
+ message=data.get("message", ""),
751
+ )
752
+
753
+ def to_dict(self) -> dict:
754
+ return {
755
+ "analysis": self.analysis,
756
+ "system_prompt": self.system_prompt,
757
+ "message": self.message,
758
+ }
581
759
 
582
760
 
583
761
  # Default configurations
enkryptai_sdk/models.py CHANGED
@@ -29,17 +29,29 @@ class ModelClient(BaseClient):
29
29
  if isinstance(config, dict):
30
30
  config = ModelConfig.from_dict(config)
31
31
 
32
- # Parse endpoint_url into components
33
- parsed_url = urlparse(config.model_config.endpoint_url)
34
- path_parts = parsed_url.path.strip("/").split("/")
35
-
36
- # Extract base_path and endpoint path
37
- if len(path_parts) >= 1:
38
- base_path = path_parts[0] # Usually 'v1'
39
- remaining_path = "/".join(path_parts[1:]) # The rest of the path
40
- else:
41
- base_path = ""
42
- remaining_path = ""
32
+ endpoint_data = {}
33
+ base_path = ""
34
+ remaining_path = ""
35
+
36
+ if config.model_config.endpoint_url:
37
+ # Parse endpoint_url into components
38
+ parsed_url = urlparse(config.model_config.endpoint_url)
39
+ path_parts = parsed_url.path.strip("/").split("/")
40
+
41
+ # Extract base_path and endpoint path
42
+ if len(path_parts) >= 1:
43
+ base_path = path_parts[0] # Usually 'v1'
44
+ remaining_path = "/".join(path_parts[1:]) # The rest of the path
45
+ else:
46
+ base_path = ""
47
+ remaining_path = ""
48
+
49
+ endpoint_data = {
50
+ "scheme": parsed_url.scheme,
51
+ "host": parsed_url.hostname,
52
+ "port": parsed_url.port or (443 if parsed_url.scheme == "https" else 80),
53
+ "base_path": f"/{base_path}",
54
+ }
43
55
 
44
56
  if config.model_config.paths:
45
57
  paths = config.model_config.paths.to_dict()
@@ -61,12 +73,7 @@ class ModelClient(BaseClient):
61
73
  "hosting_type": config.model_config.hosting_type,
62
74
  "model_source": config.model_config.model_source,
63
75
  "system_prompt": config.model_config.system_prompt,
64
- "endpoint": {
65
- "scheme": parsed_url.scheme,
66
- "host": parsed_url.hostname,
67
- "port": parsed_url.port or (443 if parsed_url.scheme == "https" else 80),
68
- "base_path": f"/{base_path}",
69
- },
76
+ "endpoint": endpoint_data,
70
77
  "paths": paths,
71
78
  "auth_data": {
72
79
  "header_name": config.model_config.auth_data.header_name,
@@ -149,92 +156,33 @@ class ModelClient(BaseClient):
149
156
  except Exception as e:
150
157
  return {"error": str(e)}
151
158
 
152
- def modify_model(self, config: ModelConfig, old_model_saved_name=None, old_model_version=None) -> ModelResponse:
159
+ def modify_model(self, config: ModelConfig | dict, old_model_saved_name=None, old_model_version=None) -> ModelResponse:
153
160
  """
154
161
  Modify an existing model in the system.
155
162
 
156
163
  Args:
157
- old_model_saved_name (str): The old saved name of the model to modify
158
- old_model_version (str): The old version of the model to modify
159
- config (ModelConfig): Configuration object containing model details
164
+ config (Union[ModelConfig, dict]): Configuration object or dictionary containing model details
165
+ old_model_saved_name (str, optional): The old saved name of the model to modify. Defaults to None.
166
+ old_model_version (str, optional): The old version of the model to modify. Defaults to None.
160
167
 
161
168
  Returns:
162
169
  dict: Response from the API containing the modified model details
163
170
  """
171
+
172
+ temp_config = config
173
+ if isinstance(temp_config, dict):
174
+ temp_config = ModelConfig.from_dict(temp_config)
175
+
164
176
  if old_model_saved_name is None:
165
- old_model_saved_name = config["model_saved_name"]
177
+ old_model_saved_name = temp_config.model_saved_name
166
178
 
167
179
  if old_model_version is None:
168
- old_model_version = config["model_version"]
180
+ old_model_version = temp_config.model_version
169
181
 
170
182
  headers = {"Content-Type": "application/json", "X-Enkrypt-Model": old_model_saved_name, "X-Enkrypt-Model-Version": old_model_version}
171
- # print(config)
172
- config = ModelConfig.from_dict(config)
173
- # Parse endpoint_url into components
174
- parsed_url = urlparse(config.model_config.endpoint_url)
175
- path_parts = parsed_url.path.strip("/").split("/")
176
-
177
- # Extract base_path and endpoint path
178
- if len(path_parts) >= 1:
179
- base_path = path_parts[0] # Usually 'v1'
180
- remaining_path = "/".join(path_parts[1:]) # The rest of the path
181
- else:
182
- base_path = ""
183
- remaining_path = ""
184
-
185
- if config.model_config.paths:
186
- paths = config.model_config.paths.to_dict()
187
- else:
188
- # Determine paths based on the endpoint
189
- paths = {
190
- "completions": (
191
- f"/{remaining_path.split('/')[-1]}" if remaining_path else ""
192
- ),
193
- "chat": f"/{remaining_path}" if remaining_path else "",
194
- }
195
-
196
- # Convert custom_headers to list of dictionaries
197
- custom_headers = [header.to_dict() for header in config.model_config.custom_headers]
183
+
184
+ payload = self.prepare_model_payload(temp_config)
198
185
 
199
- payload = {
200
- "model_saved_name": config.model_saved_name,
201
- "model_version": config.model_version,
202
- "testing_for": config.testing_for,
203
- "model_name": config.model_name,
204
- "certifications": config.certifications,
205
- "model_config": {
206
- "model_provider": config.model_config.model_provider,
207
- "hosting_type": config.model_config.hosting_type,
208
- "model_source": config.model_config.model_source,
209
- "system_prompt": config.model_config.system_prompt,
210
- "endpoint": {
211
- "scheme": parsed_url.scheme,
212
- "host": parsed_url.hostname,
213
- "port": parsed_url.port
214
- or (443 if parsed_url.scheme == "https" else 80),
215
- "base_path": f"/{base_path}", # Just v1
216
- },
217
- "paths": paths,
218
- "auth_data": {
219
- "header_name": config.model_config.auth_data.header_name,
220
- "header_prefix": config.model_config.auth_data.header_prefix,
221
- "space_after_prefix": config.model_config.auth_data.space_after_prefix,
222
- },
223
- "apikeys": (
224
- [config.model_config.apikey] if config.model_config.apikey else []
225
- ),
226
- "tools": config.model_config.tools,
227
- "input_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.input_modalities],
228
- "output_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.output_modalities],
229
- "custom_curl_command": config.model_config.custom_curl_command,
230
- "custom_headers": custom_headers,
231
- "custom_payload": config.model_config.custom_payload,
232
- "custom_response_content_type": config.model_config.custom_response_content_type,
233
- "custom_response_format": config.model_config.custom_response_format,
234
- "metadata": config.model_config.metadata,
235
- "default_request_options": config.model_config.default_request_options,
236
- },
237
- }
238
186
  try:
239
187
  response = self._request(
240
188
  "PATCH", "/models/modify-model", headers=headers, json=payload
enkryptai_sdk/red_team.py CHANGED
@@ -17,6 +17,10 @@ from .dto import (
17
17
  RedTeamTaskStatus,
18
18
  RedTeamTaskDetails,
19
19
  RedTeamTaskList,
20
+ RedTeamRiskMitigationGuardrailsPolicyConfig,
21
+ RedTeamRiskMitigationGuardrailsPolicyResponse,
22
+ RedTeamRiskMitigationSystemPromptConfig,
23
+ RedTeamRiskMitigationSystemPromptResponse,
20
24
  )
21
25
 
22
26
 
@@ -508,3 +512,27 @@ class RedTeamClient(BaseClient):
508
512
  if isinstance(response, dict) and response.get("error"):
509
513
  raise RedTeamClientError(f"API Error: {str(response)}")
510
514
  return RedTeamTaskList.from_dict(response)
515
+
516
+ def risk_mitigation_guardrails_policy(self, config: RedTeamRiskMitigationGuardrailsPolicyConfig):
517
+ """
518
+ Get the guardrails policy generated for risk mitigation.
519
+ """
520
+ config = RedTeamRiskMitigationGuardrailsPolicyConfig.from_dict(config)
521
+ payload = config.to_dict()
522
+
523
+ response = self._request("POST", "/redteam/risk-mitigation/guardrails-policy", json=payload)
524
+ if isinstance(response, dict) and response.get("error"):
525
+ raise RedTeamClientError(f"API Error: {str(response)}")
526
+ return RedTeamRiskMitigationGuardrailsPolicyResponse.from_dict(response)
527
+
528
+ def risk_mitigation_system_prompt(self, config: RedTeamRiskMitigationSystemPromptConfig):
529
+ """
530
+ Get the system prompt generated for risk mitigation.
531
+ """
532
+ config = RedTeamRiskMitigationSystemPromptConfig.from_dict(config)
533
+ payload = config.to_dict()
534
+
535
+ response = self._request("POST", "/redteam/risk-mitigation/system-prompt", json=payload)
536
+ if isinstance(response, dict) and response.get("error"):
537
+ raise RedTeamClientError(f"API Error: {str(response)}")
538
+ return RedTeamRiskMitigationSystemPromptResponse.from_dict(response)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enkryptai-sdk
3
- Version: 1.0.14
3
+ Version: 1.0.16
4
4
  Summary: A Python SDK with guardrails and red teaming functionality for API interactions
5
5
  Home-page: https://github.com/enkryptai/enkryptai-sdk
6
6
  Author: Enkrypt AI Team
@@ -49,6 +49,8 @@ Also see the API documentation at [https://docs.enkryptai.com](https://docs.enkr
49
49
  - [Sample Redteam Model Config](#sample-redteam-model-config)
50
50
  - [Sample Custom Redteam Target Config](#sample-custom-redteam-target-config)
51
51
  - [Sample Custom Redteam Model Config](#sample-custom-redteam-model-config)
52
+ - [Sample Redteam Risk Mitigation Guardrails Policy Config](#sample-redteam-risk-mitigation-guardrails-policy-config)
53
+ - [Sample Redteam Risk Mitigation System Prompt Config](#sample-redteam-risk-mitigation-system-prompt-config)
52
54
  - [Health Checks](#health-checks)
53
55
  - [Guardrails Health](#guardrails-health)
54
56
  - [Guardrails Status](#guardrails-status)
@@ -124,6 +126,8 @@ Also see the API documentation at [https://docs.enkryptai.com](https://docs.enkr
124
126
  - [Get Redteam Task Results Summary of Test Type](#get-redteam-task-results-summary-of-test-type)
125
127
  - [Get Redteam Task Results Details](#get-redteam-task-results-details)
126
128
  - [Get Redteam Task Results Details of Test Type](#get-redteam-task-results-details-of-test-type)
129
+ - [Mitigate Risks with Guardrails Policy](#mitigate-risks-with-guardrails-policy)
130
+ - [Mitigate Risks with System Prompt](#mitigate-risks-with-system-prompt)
127
131
  - [Copyright, License, and Terms of Use](#copyright-license-and-terms-of-use)
128
132
 
129
133
  ## Installation
@@ -518,6 +522,289 @@ sample_custom_redteam_model_config = {
518
522
  }
519
523
  ```
520
524
 
525
+ ### [Sample Redteam Risk Mitigation Guardrails Policy Config](https://docs.enkryptai.com/redteam-api-reference/endpoint/risk-mitigation-guardrails-policy)
526
+
527
+ ```python Python
528
+ sample_redteam_risk_mitigation_guardrails_policy_config = {
529
+ "redteam_summary": {
530
+ "category": [
531
+ {
532
+ "Biology": {
533
+ "total": 50,
534
+ "test_type": "cbrn_test",
535
+ "success(%)": 92
536
+ }
537
+ },
538
+ {
539
+ "Chemistry": {
540
+ "total": 50,
541
+ "test_type": "cbrn_test",
542
+ "success(%)": 98
543
+ }
544
+ },
545
+ {
546
+ "Fraud": {
547
+ "total": 100,
548
+ "test_type": "harmful_test",
549
+ "success(%)": 73
550
+ }
551
+ },
552
+ {
553
+ "Guns & Illegal Substances": {
554
+ "total": 100,
555
+ "test_type": "harmful_test",
556
+ "success(%)": 87
557
+ }
558
+ },
559
+ {
560
+ "Hate Speech and Discrimination": {
561
+ "total": 100,
562
+ "test_type": "harmful_test",
563
+ "success(%)": 53
564
+ }
565
+ },
566
+ {
567
+ "Nuclear Science": {
568
+ "total": 50,
569
+ "test_type": "cbrn_test",
570
+ "success(%)": 94
571
+ }
572
+ },
573
+ {
574
+ "Radiology": {
575
+ "total": 50,
576
+ "test_type": "cbrn_test",
577
+ "success(%)": 84
578
+ }
579
+ },
580
+ {
581
+ "Regulated or Controlled Substances": {
582
+ "total": 100,
583
+ "test_type": "harmful_test",
584
+ "success(%)": 74
585
+ }
586
+ },
587
+ {
588
+ "Sexual Content": {
589
+ "total": 100,
590
+ "test_type": "harmful_test",
591
+ "success(%)": 79
592
+ }
593
+ },
594
+ {
595
+ "Suicide & Self-Harm": {
596
+ "total": 100,
597
+ "test_type": "harmful_test",
598
+ "success(%)": 72
599
+ }
600
+ },
601
+ {
602
+ "Unethical Crimes": {
603
+ "total": 100,
604
+ "test_type": "harmful_test",
605
+ "success(%)": 83
606
+ }
607
+ },
608
+ {
609
+ "Violent Crimes": {
610
+ "total": 100,
611
+ "test_type": "harmful_test",
612
+ "success(%)": 70
613
+ }
614
+ }
615
+ ],
616
+ "scenario": [],
617
+ "test_date": "2020-01-01T17:14:33.607823+00:00",
618
+ "test_name": "Mistral Small Latest x Red Team",
619
+ "test_type": [
620
+ {
621
+ "cbrn_test": {
622
+ "total": 200,
623
+ "success(%)": 92
624
+ }
625
+ },
626
+ {
627
+ "harmful_test": {
628
+ "total": 800,
629
+ "success(%)": 73.88
630
+ }
631
+ }
632
+ ],
633
+ "model_name": "mistral-small-latest",
634
+ "risk_score": 82.9375,
635
+ "dataset_name": "Standard",
636
+ "model_source": "",
637
+ "attack_method": [
638
+ {
639
+ "Basic": {
640
+ "total": 1000,
641
+ "success(%)": 77.5
642
+ }
643
+ }
644
+ ],
645
+ "nist_category": [
646
+ {
647
+ "CBRN Information or Capabilities": {
648
+ "total": 200,
649
+ "success(%)": 92
650
+ }
651
+ },
652
+ {
653
+ "Dangerous, Violent, or Hateful Content": {
654
+ "total": 800,
655
+ "success(%)": 73.88
656
+ }
657
+ }
658
+ ],
659
+ "model_provider": "mistral",
660
+ "model_endpoint_url": "https://api.mistral.ai/v1/chat/completions",
661
+ "custom_test_category_risks": []
662
+ }
663
+ }
664
+ ```
665
+
666
+ ### [Sample Redteam Risk Mitigation System Prompt Config](https://docs.enkryptai.com/redteam-api-reference/endpoint/risk-mitigation-system-prompt)
667
+
668
+ ```python Python
669
+ sample_redteam_risk_mitigation_system_prompt_config = {
670
+ "system_prompt": "You are a helpful AI Assistant",
671
+ "redteam_summary": {
672
+ "category": [
673
+ {
674
+ "Biology": {
675
+ "total": 50,
676
+ "test_type": "cbrn_test",
677
+ "success(%)": 92
678
+ }
679
+ },
680
+ {
681
+ "Chemistry": {
682
+ "total": 50,
683
+ "test_type": "cbrn_test",
684
+ "success(%)": 98
685
+ }
686
+ },
687
+ {
688
+ "Fraud": {
689
+ "total": 100,
690
+ "test_type": "harmful_test",
691
+ "success(%)": 73
692
+ }
693
+ },
694
+ {
695
+ "Guns & Illegal Substances": {
696
+ "total": 100,
697
+ "test_type": "harmful_test",
698
+ "success(%)": 87
699
+ }
700
+ },
701
+ {
702
+ "Hate Speech and Discrimination": {
703
+ "total": 100,
704
+ "test_type": "harmful_test",
705
+ "success(%)": 53
706
+ }
707
+ },
708
+ {
709
+ "Nuclear Science": {
710
+ "total": 50,
711
+ "test_type": "cbrn_test",
712
+ "success(%)": 94
713
+ }
714
+ },
715
+ {
716
+ "Radiology": {
717
+ "total": 50,
718
+ "test_type": "cbrn_test",
719
+ "success(%)": 84
720
+ }
721
+ },
722
+ {
723
+ "Regulated or Controlled Substances": {
724
+ "total": 100,
725
+ "test_type": "harmful_test",
726
+ "success(%)": 74
727
+ }
728
+ },
729
+ {
730
+ "Sexual Content": {
731
+ "total": 100,
732
+ "test_type": "harmful_test",
733
+ "success(%)": 79
734
+ }
735
+ },
736
+ {
737
+ "Suicide & Self-Harm": {
738
+ "total": 100,
739
+ "test_type": "harmful_test",
740
+ "success(%)": 72
741
+ }
742
+ },
743
+ {
744
+ "Unethical Crimes": {
745
+ "total": 100,
746
+ "test_type": "harmful_test",
747
+ "success(%)": 83
748
+ }
749
+ },
750
+ {
751
+ "Violent Crimes": {
752
+ "total": 100,
753
+ "test_type": "harmful_test",
754
+ "success(%)": 70
755
+ }
756
+ }
757
+ ],
758
+ "scenario": [],
759
+ "test_date": "2020-01-01T17:14:33.607823+00:00",
760
+ "test_name": "Mistral Small Latest x Red Team",
761
+ "test_type": [
762
+ {
763
+ "cbrn_test": {
764
+ "total": 200,
765
+ "success(%)": 92
766
+ }
767
+ },
768
+ {
769
+ "harmful_test": {
770
+ "total": 800,
771
+ "success(%)": 73.88
772
+ }
773
+ }
774
+ ],
775
+ "model_name": "mistral-small-latest",
776
+ "risk_score": 82.9375,
777
+ "dataset_name": "Standard",
778
+ "model_source": "",
779
+ "attack_method": [
780
+ {
781
+ "Basic": {
782
+ "total": 1000,
783
+ "success(%)": 77.5
784
+ }
785
+ }
786
+ ],
787
+ "nist_category": [
788
+ {
789
+ "CBRN Information or Capabilities": {
790
+ "total": 200,
791
+ "success(%)": 92
792
+ }
793
+ },
794
+ {
795
+ "Dangerous, Violent, or Hateful Content": {
796
+ "total": 800,
797
+ "success(%)": 73.88
798
+ }
799
+ }
800
+ ],
801
+ "model_provider": "mistral",
802
+ "model_endpoint_url": "https://api.mistral.ai/v1/chat/completions",
803
+ "custom_test_category_risks": []
804
+ }
805
+ }
806
+ ```
807
+
521
808
  ## Health Checks
522
809
 
523
810
  ### [Guardrails Health](https://docs.enkryptai.com/guardrails-api-reference/endpoint/health-check)
@@ -694,8 +981,8 @@ print(batch_detect_response.to_dict())
694
981
  - `nsfw`: Filter inappropriate content
695
982
  - `toxicity`: Detect toxic language
696
983
  - `pii`: Detect personal information
697
- - `copyright_ip`: Check for copyright/IP violations *(Coming soon)*
698
- - `system_prompt`: Detect system prompt leaks *(Coming soon)*
984
+ - `copyright_ip`: Check for copyright/IP violations ***(Coming soon)***
985
+ - `system_prompt`: Detect system prompt leaks ***(Coming soon)***
699
986
  - `keyword_detector`: Check for specific keywords
700
987
 
701
988
  Each detector can be enabled/disabled and configured with specific options as documented in the [API docs](https://docs.enkryptai.com/guardrails-api-reference/introduction).
@@ -757,7 +1044,7 @@ guardrails_config = GuardrailsConfig.keyword(keywords=["secret", "password"])
757
1044
 
758
1045
  ### [Copyright IP](https://docs.enkryptai.com/guardrails-api-reference/Copyright_IP_Leak_Detector)
759
1046
 
760
- *(Coming soon)*
1047
+ - ***(Coming soon)***
761
1048
 
762
1049
  ```python Python
763
1050
  guardrails_config = GuardrailsConfig.copyright_ip()
@@ -765,7 +1052,7 @@ guardrails_config = GuardrailsConfig.copyright_ip()
765
1052
 
766
1053
  ### [System Prompt](https://docs.enkryptai.com/guardrails-api-reference/System_Prompt_Leak_Detector)
767
1054
 
768
- *(Coming soon)*
1055
+ - ***(Coming soon)***
769
1056
 
770
1057
  ```python Python
771
1058
  guardrails_config = GuardrailsConfig.system_prompt(index="system")
@@ -969,7 +1256,7 @@ print(relevancy_response.to_dict())
969
1256
 
970
1257
  ### [Check Hallucination](https://docs.enkryptai.com/guardrails-api-reference/Hallucination)
971
1258
 
972
- *(Coming soon)*
1259
+ - ***(Coming soon)***
973
1260
 
974
1261
  Detect hallucinations in an LLM's response:
975
1262
 
@@ -1660,6 +1947,32 @@ print(redteam_results_details_test_type.task_status)
1660
1947
  print(redteam_results_details_test_type.to_dict())
1661
1948
  ```
1662
1949
 
1950
+ ### [Mitigate Risks with Guardrails Policy](https://docs.enkryptai.com/redteam-api-reference/endpoint/risk-mitigation-guardrails-policy)
1951
+
1952
+ ```python Python
1953
+ # Mitigate risks with guardrails policy
1954
+ risk_mitigation_guardrails_policy_response = redteam_client.risk_mitigation_guardrails_policy(config=copy.deepcopy(sample_redteam_risk_mitigation_guardrails_policy_config))
1955
+
1956
+ print(risk_mitigation_guardrails_policy_response)
1957
+ print(risk_mitigation_guardrails_policy_response.guardrails_policy)
1958
+
1959
+ # Print as a dictionary
1960
+ print(risk_mitigation_guardrails_policy_response.to_dict())
1961
+ ```
1962
+
1963
+ ### [Mitigate Risks with System Prompt](https://docs.enkryptai.com/redteam-api-reference/endpoint/risk-mitigation-system-prompt)
1964
+
1965
+ ```python Python
1966
+ # Mitigate risks with system prompt
1967
+ risk_mitigation_system_prompt_response = redteam_client.risk_mitigation_system_prompt(config=copy.deepcopy(sample_redteam_risk_mitigation_system_prompt_config))
1968
+
1969
+ print(risk_mitigation_system_prompt_response)
1970
+ print(risk_mitigation_system_prompt_response.system_prompt)
1971
+
1972
+ # Print as a dictionary
1973
+ print(risk_mitigation_system_prompt_response.to_dict())
1974
+ ```
1975
+
1663
1976
  ## Copyright, License and Terms of Use
1664
1977
 
1665
1978
  © 2025 Enkrypt AI. All rights reserved.
@@ -8,8 +8,8 @@ enkryptai_sdk/deployments.py,sha256=A7XZ2JwrMod9V4_aV8bFY_Soh9E3jHdwaTuJ9BwXuyk,
8
8
  enkryptai_sdk/evals.py,sha256=BywyEgIT7xdJ58svO_sDNOMVowdB0RTGoAZPEbCnDVo,2595
9
9
  enkryptai_sdk/guardrails.py,sha256=NluimOA0gM9N3S_q47LTUeG97t9PlYqPHlZahDPkJvI,16365
10
10
  enkryptai_sdk/guardrails_old.py,sha256=SgzPZkTzbAPD9XfmYNG6M1-TrzbhDHpAkI3FjnVWS_s,6434
11
- enkryptai_sdk/models.py,sha256=rrLTT3i96flWidVrr67j6VZ6XmkdxwEzlF4S4aoVmOQ,11559
12
- enkryptai_sdk/red_team.py,sha256=A1b6R5d3dtZMfb5npBrSu4RX2X-C9V4hubyO9g3BZlA,18441
11
+ enkryptai_sdk/models.py,sha256=OfADGvP2gy52_fXT5iAj81Q07iDGAEYWiKYLD_ycozU,8786
12
+ enkryptai_sdk/red_team.py,sha256=cjN4LODbpYiECcoL0JROMcCPCzm3Ib6kXi7kQspP4hQ,19869
13
13
  enkryptai_sdk/response.py,sha256=43JRubzgGCpoVxYNzBZY0AlUgLbfcXD_AwD7wU3qY9o,4086
14
14
  enkryptai_sdk/dto/__init__.py,sha256=wHgIv_OCnVMJOys-vqImF59ifogDrMcgxVRmfNayVvc,2761
15
15
  enkryptai_sdk/dto/ai_proxy.py,sha256=clwMN4xdH8Zr55dnhilHbs-qaHRlCOrLPrij0Zd1Av0,11283
@@ -17,11 +17,11 @@ enkryptai_sdk/dto/base.py,sha256=y77kQL1X7389ifSVNc0E7CUFNxACh5AM3ml9YPon1KY,282
17
17
  enkryptai_sdk/dto/coc.py,sha256=Lp2aat_24J4KuUg4BeJl9S39tEak8Bw15eJ4cQDrRQk,4749
18
18
  enkryptai_sdk/dto/datasets.py,sha256=RFA9CmbhD-QDDyweBq_k9iBd00b6I6SWmdP9DPNd9fc,5002
19
19
  enkryptai_sdk/dto/deployments.py,sha256=Aw4b8tDA3FYIomqDvCjblCXTagL4bT8Fx91X0SFXs40,11216
20
- enkryptai_sdk/dto/guardrails.py,sha256=wfKm2R0uJAq9nljLBPuuT05tj1nBqZraga-5lMHd3n8,49812
21
- enkryptai_sdk/dto/models.py,sha256=zldbvYV5zcg1J3UZh4UnaeM1cBx-_LCCyW-LtfBcjaQ,14246
22
- enkryptai_sdk/dto/red_team.py,sha256=GD_HxFhoaEixyaZLVdoLHmHDXFRf9b-Wq6RT-UJNQfM,18344
23
- enkryptai_sdk-1.0.14.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- enkryptai_sdk-1.0.14.dist-info/METADATA,sha256=m6amEeDX9HURaZab4Wn_LMISj8WmxUQ8pTRRtd3Ogwo,62009
25
- enkryptai_sdk-1.0.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- enkryptai_sdk-1.0.14.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
27
- enkryptai_sdk-1.0.14.dist-info/RECORD,,
20
+ enkryptai_sdk/dto/guardrails.py,sha256=oJQqFhsdQd_yPU187AhKse-Y4xktgmVNwwKKkzFazbg,50167
21
+ enkryptai_sdk/dto/models.py,sha256=SDzNMwxDVIp2D1qO29ere8WgqC5n_bJuitesaoxitZo,14312
22
+ enkryptai_sdk/dto/red_team.py,sha256=EHwDbDM0mMLDyGB_kN4KEOO65ng9Bn51q9O3IdwO5Ng,24766
23
+ enkryptai_sdk-1.0.16.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ enkryptai_sdk-1.0.16.dist-info/METADATA,sha256=T7ws5lOF-ynN_Z3cegMX0Ysotjp2_n7pet8Ci-ULFmI,72860
25
+ enkryptai_sdk-1.0.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ enkryptai_sdk-1.0.16.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
27
+ enkryptai_sdk-1.0.16.dist-info/RECORD,,