lexsi-sdk 0.1.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.
Files changed (40) hide show
  1. lexsi_sdk/__init__.py +5 -0
  2. lexsi_sdk/client/__init__.py +0 -0
  3. lexsi_sdk/client/client.py +176 -0
  4. lexsi_sdk/common/__init__.py +0 -0
  5. lexsi_sdk/common/config/.env.prod +3 -0
  6. lexsi_sdk/common/constants.py +143 -0
  7. lexsi_sdk/common/enums.py +8 -0
  8. lexsi_sdk/common/environment.py +49 -0
  9. lexsi_sdk/common/monitoring.py +81 -0
  10. lexsi_sdk/common/trigger.py +75 -0
  11. lexsi_sdk/common/types.py +122 -0
  12. lexsi_sdk/common/utils.py +93 -0
  13. lexsi_sdk/common/validation.py +110 -0
  14. lexsi_sdk/common/xai_uris.py +197 -0
  15. lexsi_sdk/core/__init__.py +0 -0
  16. lexsi_sdk/core/agent.py +62 -0
  17. lexsi_sdk/core/alert.py +56 -0
  18. lexsi_sdk/core/case.py +618 -0
  19. lexsi_sdk/core/dashboard.py +131 -0
  20. lexsi_sdk/core/guardrails/__init__.py +0 -0
  21. lexsi_sdk/core/guardrails/guard_template.py +299 -0
  22. lexsi_sdk/core/guardrails/guardrail_autogen.py +554 -0
  23. lexsi_sdk/core/guardrails/guardrails_langgraph.py +525 -0
  24. lexsi_sdk/core/guardrails/guardrails_openai.py +541 -0
  25. lexsi_sdk/core/guardrails/openai_runner.py +1328 -0
  26. lexsi_sdk/core/model_summary.py +110 -0
  27. lexsi_sdk/core/organization.py +549 -0
  28. lexsi_sdk/core/project.py +5131 -0
  29. lexsi_sdk/core/synthetic.py +387 -0
  30. lexsi_sdk/core/text.py +595 -0
  31. lexsi_sdk/core/tracer.py +208 -0
  32. lexsi_sdk/core/utils.py +36 -0
  33. lexsi_sdk/core/workspace.py +325 -0
  34. lexsi_sdk/core/wrapper.py +766 -0
  35. lexsi_sdk/core/xai.py +306 -0
  36. lexsi_sdk/version.py +34 -0
  37. lexsi_sdk-0.1.16.dist-info/METADATA +100 -0
  38. lexsi_sdk-0.1.16.dist-info/RECORD +40 -0
  39. lexsi_sdk-0.1.16.dist-info/WHEEL +5 -0
  40. lexsi_sdk-0.1.16.dist-info/top_level.txt +1 -0
@@ -0,0 +1,131 @@
1
+ from __future__ import annotations
2
+ import os
3
+ from typing import Any
4
+ from pydantic import BaseModel
5
+ import json
6
+ from IPython.display import IFrame, display, HTML
7
+ from lexsi_sdk.common.xai_uris import XAI_APP_URI
8
+
9
+ DASHBOARD_TYPES = [
10
+ "data_drift",
11
+ "target_drift",
12
+ "performance",
13
+ "biasmonitoring",
14
+ "image_property_drift",
15
+ "label_drift",
16
+ "property_label_correlation",
17
+ "image_dataset_drift",
18
+ ]
19
+
20
+
21
+ class Dashboard(BaseModel):
22
+ """Client-side wrapper for visualizing generated dashboards."""
23
+ config: dict
24
+ query_params: str
25
+ raw_data: dict | list | str
26
+
27
+ def __init__(self, **kwargs):
28
+ """Print configuration then render the dashboard frame."""
29
+ super().__init__(**kwargs)
30
+
31
+ self.print_config()
32
+ self.plot()
33
+
34
+ def plot(self, width: int = "100%", height: int = 800):
35
+ """plot the dashboard by remote url
36
+
37
+ :param width: Width of the embedded frame.
38
+ :param height: Height of the embedded frame.
39
+ """
40
+ if isinstance(self.raw_data, str) and "</html>" in self.raw_data:
41
+ display(HTML(self.raw_data))
42
+ else:
43
+ uri = os.environ.get("XAI_APP_URL", XAI_APP_URI)
44
+ url = f"{uri}/sdk/dashboard{self.query_params}"
45
+ display(IFrame(src=f"{url}", width=width, height=height))
46
+
47
+ def get_config(self) -> dict:
48
+ """
49
+ get the dashboard config
50
+ """
51
+ config_copy = {**self.config}
52
+ config_copy.pop("metadata", None)
53
+ return config_copy
54
+
55
+ def get_raw_data(self) -> dict:
56
+ """
57
+ get the dashboard raw data
58
+ """
59
+ raw_data = {"created_at": self.config.get("created_at")}
60
+
61
+ if self.config["type"] == "data_drift":
62
+ data_drift_table = next(
63
+ filter(
64
+ lambda data: data["metric"] == "DataDriftTable",
65
+ self.raw_data.get("metrics"),
66
+ ),
67
+ None,
68
+ )
69
+ if data_drift_table:
70
+ for item in data_drift_table["result"].get("drift_by_columns"):
71
+ item.pop("current_small_distribution", None)
72
+ item.pop("reference_small_distribution", None)
73
+ item.pop("current_big_distribution", None)
74
+ item.pop("reference_big_distribution", None)
75
+ item.pop("current_mean", None)
76
+ item.pop("reference_std", None)
77
+ raw_data.update(data_drift_table["result"])
78
+
79
+ if self.config["type"] == "target_drift":
80
+ column_drift_metric = next(
81
+ filter(
82
+ lambda data: data["metric"] == "ColumnDriftMetric",
83
+ self.raw_data.get("metrics"),
84
+ ),
85
+ None,
86
+ )
87
+ if column_drift_metric:
88
+ column_drift_metric["result"].pop("data", None)
89
+
90
+ raw_data.update(column_drift_metric["result"])
91
+
92
+ if self.config["type"] == "performance":
93
+ classification_quality_metric = next(
94
+ filter(
95
+ lambda data: data["metric"] == "ClassificationQualityMetric",
96
+ self.raw_data.get("metrics"),
97
+ ),
98
+ None,
99
+ )
100
+ if classification_quality_metric:
101
+ for curr_ref in ["current", "reference"]:
102
+ classification_quality_metric["result"][curr_ref].pop(
103
+ "rate_plots_data", None
104
+ )
105
+ classification_quality_metric["result"][curr_ref].pop(
106
+ "plot_data", None
107
+ )
108
+ raw_data.update(classification_quality_metric["result"])
109
+
110
+ return raw_data
111
+
112
+ def print_config(self):
113
+ """
114
+ pretty print the cdashboard config
115
+ """
116
+ config = {k: v for k, v in self.config.items() if v is not None}
117
+ config.pop("metadata", None)
118
+ print("Using config: ", end="")
119
+ print(json.dumps(config, indent=4))
120
+
121
+ def __print__(self) -> str:
122
+ """User-friendly string representation."""
123
+ return f"Dashboard(config='{self.get_config()}')"
124
+
125
+ def __str__(self) -> str:
126
+ """Return printable representation."""
127
+ return self.__print__()
128
+
129
+ def __repr__(self) -> str:
130
+ """Return developer-friendly representation."""
131
+ return self.__print__()
File without changes
@@ -0,0 +1,299 @@
1
+ from typing import Any, Callable, Dict, List, Optional, Tuple, TypedDict, Union
2
+
3
+ class Guard:
4
+ """Predefined guardrail configurations for common use cases"""
5
+
6
+ @staticmethod
7
+ def detect_pii(entities: List[str] = None) -> Dict[str, Any]:
8
+ """Template for PII detection guardrail
9
+
10
+ :param entities: List of PII entity types to detect.
11
+ """
12
+ if entities is None:
13
+ entities = ["EMAIL_ADDRESS", "PHONE_NUMBER", "PERSON", "ADDRESS"]
14
+
15
+ return {
16
+ "name": "Detect PII",
17
+ "config": {
18
+ "pii_entities": entities
19
+ }
20
+ }
21
+
22
+ @staticmethod
23
+ def nsfw_text(threshold: float = 0.8, validation_method: str = "sentence") -> Dict[str, Any]:
24
+ """Template for NSFW text detection guardrail
25
+
26
+ :param threshold: Confidence threshold for detection (0.0-1.0).
27
+ :param validation_method: Validation scope: "sentence", "paragraph", or "document".
28
+ """
29
+ return {
30
+ "name": "NSFW Text",
31
+ "config": {
32
+ "threshold": threshold,
33
+ "validation_method": validation_method
34
+ }
35
+ }
36
+ @staticmethod
37
+ def ban_list(banned_words: List[str]) -> Dict[str, Any]:
38
+ """Template for banned words guardrail"""
39
+ return {
40
+ "name": "Ban List",
41
+ "config": {
42
+ "banned_words": banned_words
43
+ }
44
+ }
45
+ @staticmethod
46
+ def bias_check(threshold: float = 0.9) -> Dict[str, Any]:
47
+ """Template for bias check guardrail"""
48
+ return {
49
+ "name": "Bias Check",
50
+ "config": {
51
+ "threshold": threshold
52
+ }
53
+ }
54
+
55
+ @staticmethod
56
+ def competitor_check(competitors: List[str]) -> Dict[str, Any]:
57
+ """Template for competitor guardrail"""
58
+ return {
59
+ "name": "Competitor Check",
60
+ "config": {
61
+ "competitors": competitors
62
+ }
63
+ }
64
+
65
+ @staticmethod
66
+ def correct_language(expected_language_iso: str = "en", threshold: float = 0.75) -> Dict[str, Any]:
67
+ """Template for correct language guardrail"""
68
+ return {
69
+ "name": "Correct Language",
70
+ "config": {
71
+ "expected_language_iso": expected_language_iso,
72
+ "threshold": threshold
73
+ }
74
+ }
75
+
76
+ @staticmethod
77
+ def gibberish_text(threshold: float = 0.5, validation_method: str = "sentence") -> Dict[str, Any]:
78
+ """Template for gibberish text guardrail"""
79
+ return {
80
+ "name": "Gibberish Text",
81
+ "config": {
82
+ "threshold": threshold,
83
+ "validation_method": validation_method
84
+ }
85
+ }
86
+
87
+ @staticmethod
88
+ def profanity_free() -> Dict[str, Any]:
89
+ """Template for profanity free guardrail"""
90
+ return {
91
+ "name": "Profanity Free",
92
+ "config": {}
93
+ }
94
+
95
+ @staticmethod
96
+ def secrets_present() -> Dict[str, Any]:
97
+ """Template for secrets present guardrail"""
98
+ return {
99
+ "name": "Secrets Present",
100
+ "config": {}
101
+ }
102
+
103
+ @staticmethod
104
+ def toxic_language(threshold: float = 0.5, validation_method: str = "sentence") -> Dict[str, Any]:
105
+ """Template for toxic language guardrail"""
106
+ return {
107
+ "name": "Toxic Language",
108
+ "config": {
109
+ "threshold": threshold,
110
+ "validation_method": validation_method
111
+ }
112
+ }
113
+
114
+ @staticmethod
115
+ def contains_string(substring: str) -> Dict[str, Any]:
116
+ """Template for contains string guardrail"""
117
+ return {
118
+ "name": "Contains String",
119
+ "config": {
120
+ "substring": substring
121
+ }
122
+ }
123
+
124
+ @staticmethod
125
+ def detect_jailbreak(threshold: float = 0.0) -> Dict[str, Any]:
126
+ """Template for detect jailbreak guardrail"""
127
+ return {
128
+ "name": "Detect Jailbreak",
129
+ "config": {
130
+ "threshold": threshold
131
+ }
132
+ }
133
+
134
+ @staticmethod
135
+ def endpoint_is_reachable() -> Dict[str, Any]:
136
+ """Template for endpoint is reachable guardrail"""
137
+ return {
138
+ "name": "Endpoint Is Reachable",
139
+ "config": {}
140
+ }
141
+
142
+ @staticmethod
143
+ def ends_with(end: str) -> Dict[str, Any]:
144
+ """Template for ends with guardrail"""
145
+ return {
146
+ "name": "Ends With",
147
+ "config": {
148
+ "end": end
149
+ }
150
+ }
151
+
152
+ @staticmethod
153
+ def has_url() -> Dict[str, Any]:
154
+ """Template for has url guardrail"""
155
+ return {
156
+ "name": "Has Url",
157
+ "config": {}
158
+ }
159
+
160
+ @staticmethod
161
+ def lower_case() -> Dict[str, Any]:
162
+ """Template for lower case guardrail"""
163
+ return {
164
+ "name": "Lower Case",
165
+ "config": {}
166
+ }
167
+
168
+ @staticmethod
169
+ def mentions_drugs() -> Dict[str, Any]:
170
+ """Template for mentions drugs guardrail"""
171
+ return {
172
+ "name": "Mentions Drugs",
173
+ "config": {}
174
+ }
175
+
176
+ @staticmethod
177
+ def one_line() -> Dict[str, Any]:
178
+ """Template for one line guardrail"""
179
+ return {
180
+ "name": "One Line",
181
+ "config": {}
182
+ }
183
+
184
+ @staticmethod
185
+ def reading_time(reading_time: float) -> Dict[str, Any]:
186
+ """Template for reading time guardrail"""
187
+ return {
188
+ "name": "Reading Time",
189
+ "config": {
190
+ "reading_time": reading_time
191
+ }
192
+ }
193
+
194
+ @staticmethod
195
+ def redundant_sentences(threshold: int = 70) -> Dict[str, Any]:
196
+ """Template for redundant sentences guardrail"""
197
+ return {
198
+ "name": "Redundant Sentences",
199
+ "config": {
200
+ "threshold": threshold
201
+ }
202
+ }
203
+
204
+ @staticmethod
205
+ def regex_match(regex: str, match_type: str = "search") -> Dict[str, Any]:
206
+ """Template for regex match guardrail"""
207
+ return {
208
+ "name": "Regex Match",
209
+ "config": {
210
+ "regex": regex,
211
+ "match_type": match_type
212
+ }
213
+ }
214
+
215
+ @staticmethod
216
+ def sql_column_presence(cols: List[str]) -> Dict[str, Any]:
217
+ """Template for SQL column presence guardrail"""
218
+ return {
219
+ "name": "Sql Column Presence",
220
+ "config": {
221
+ "cols": cols
222
+ }
223
+ }
224
+
225
+ @staticmethod
226
+ def two_words() -> Dict[str, Any]:
227
+ """Template for two words guardrail"""
228
+ return {
229
+ "name": "Two Words",
230
+ "config": {}
231
+ }
232
+
233
+ @staticmethod
234
+ def upper_case() -> Dict[str, Any]:
235
+ """Template for upper case guardrail"""
236
+ return {
237
+ "name": "Upper Case",
238
+ "config": {}
239
+ }
240
+
241
+ @staticmethod
242
+ def valid_choices(choices: List[str]) -> Dict[str, Any]:
243
+ """Template for valid choices guardrail"""
244
+ return {
245
+ "name": "Valid Choices",
246
+ "config": {
247
+ "choices": choices
248
+ }
249
+ }
250
+
251
+ @staticmethod
252
+ def valid_json() -> Dict[str, Any]:
253
+ """Template for valid json guardrail"""
254
+ return {
255
+ "name": "Valid Json",
256
+ "config": {}
257
+ }
258
+
259
+ @staticmethod
260
+ def valid_length(min: Optional[int] = None, max: Optional[int] = None) -> Dict[str, Any]:
261
+ """Template for valid length guardrail"""
262
+ config = {}
263
+ if min is not None:
264
+ config['min'] = min
265
+ if max is not None:
266
+ config['max'] = max
267
+ return {
268
+ "name": "Valid Length",
269
+ "config": config
270
+ }
271
+
272
+ @staticmethod
273
+ def valid_range(min: Optional[int] = None, max: Optional[int] = None) -> Dict[str, Any]:
274
+ """Template for valid range guardrail"""
275
+ config = {}
276
+ if min is not None:
277
+ config['min'] = min
278
+ if max is not None:
279
+ config['max'] = max
280
+ return {
281
+ "name": "Valid Range",
282
+ "config": config
283
+ }
284
+
285
+ @staticmethod
286
+ def valid_url() -> Dict[str, Any]:
287
+ """Template for valid url guardrail"""
288
+ return {
289
+ "name": "Valid URL",
290
+ "config": {}
291
+ }
292
+
293
+ @staticmethod
294
+ def web_sanitization() -> Dict[str, Any]:
295
+ """Template for web sanitization guardrail"""
296
+ return {
297
+ "name": "Web Sanitization",
298
+ "config": {}
299
+ }