ai-lib-python 0.5.0__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 (84) hide show
  1. ai_lib_python/__init__.py +43 -0
  2. ai_lib_python/batch/__init__.py +15 -0
  3. ai_lib_python/batch/collector.py +244 -0
  4. ai_lib_python/batch/executor.py +224 -0
  5. ai_lib_python/cache/__init__.py +26 -0
  6. ai_lib_python/cache/backends.py +380 -0
  7. ai_lib_python/cache/key.py +237 -0
  8. ai_lib_python/cache/manager.py +332 -0
  9. ai_lib_python/client/__init__.py +37 -0
  10. ai_lib_python/client/builder.py +528 -0
  11. ai_lib_python/client/cancel.py +368 -0
  12. ai_lib_python/client/core.py +433 -0
  13. ai_lib_python/client/response.py +134 -0
  14. ai_lib_python/embeddings/__init__.py +36 -0
  15. ai_lib_python/embeddings/client.py +339 -0
  16. ai_lib_python/embeddings/types.py +234 -0
  17. ai_lib_python/embeddings/vectors.py +246 -0
  18. ai_lib_python/errors/__init__.py +41 -0
  19. ai_lib_python/errors/base.py +316 -0
  20. ai_lib_python/errors/classification.py +210 -0
  21. ai_lib_python/guardrails/__init__.py +35 -0
  22. ai_lib_python/guardrails/base.py +336 -0
  23. ai_lib_python/guardrails/filters.py +583 -0
  24. ai_lib_python/guardrails/validators.py +475 -0
  25. ai_lib_python/pipeline/__init__.py +55 -0
  26. ai_lib_python/pipeline/accumulate.py +248 -0
  27. ai_lib_python/pipeline/base.py +240 -0
  28. ai_lib_python/pipeline/decode.py +281 -0
  29. ai_lib_python/pipeline/event_map.py +506 -0
  30. ai_lib_python/pipeline/fan_out.py +284 -0
  31. ai_lib_python/pipeline/select.py +297 -0
  32. ai_lib_python/plugins/__init__.py +32 -0
  33. ai_lib_python/plugins/base.py +294 -0
  34. ai_lib_python/plugins/hooks.py +296 -0
  35. ai_lib_python/plugins/middleware.py +285 -0
  36. ai_lib_python/plugins/registry.py +294 -0
  37. ai_lib_python/protocol/__init__.py +71 -0
  38. ai_lib_python/protocol/loader.py +317 -0
  39. ai_lib_python/protocol/manifest.py +385 -0
  40. ai_lib_python/protocol/validator.py +460 -0
  41. ai_lib_python/py.typed +1 -0
  42. ai_lib_python/resilience/__init__.py +102 -0
  43. ai_lib_python/resilience/backpressure.py +225 -0
  44. ai_lib_python/resilience/circuit_breaker.py +318 -0
  45. ai_lib_python/resilience/executor.py +343 -0
  46. ai_lib_python/resilience/fallback.py +341 -0
  47. ai_lib_python/resilience/preflight.py +413 -0
  48. ai_lib_python/resilience/rate_limiter.py +291 -0
  49. ai_lib_python/resilience/retry.py +299 -0
  50. ai_lib_python/resilience/signals.py +283 -0
  51. ai_lib_python/routing/__init__.py +118 -0
  52. ai_lib_python/routing/manager.py +593 -0
  53. ai_lib_python/routing/strategy.py +345 -0
  54. ai_lib_python/routing/types.py +397 -0
  55. ai_lib_python/structured/__init__.py +33 -0
  56. ai_lib_python/structured/json_mode.py +281 -0
  57. ai_lib_python/structured/schema.py +316 -0
  58. ai_lib_python/structured/validator.py +334 -0
  59. ai_lib_python/telemetry/__init__.py +127 -0
  60. ai_lib_python/telemetry/exporters/__init__.py +9 -0
  61. ai_lib_python/telemetry/exporters/prometheus.py +111 -0
  62. ai_lib_python/telemetry/feedback.py +446 -0
  63. ai_lib_python/telemetry/health.py +409 -0
  64. ai_lib_python/telemetry/logger.py +389 -0
  65. ai_lib_python/telemetry/metrics.py +496 -0
  66. ai_lib_python/telemetry/tracer.py +473 -0
  67. ai_lib_python/tokens/__init__.py +25 -0
  68. ai_lib_python/tokens/counter.py +282 -0
  69. ai_lib_python/tokens/estimator.py +286 -0
  70. ai_lib_python/transport/__init__.py +34 -0
  71. ai_lib_python/transport/auth.py +141 -0
  72. ai_lib_python/transport/http.py +364 -0
  73. ai_lib_python/transport/pool.py +425 -0
  74. ai_lib_python/types/__init__.py +41 -0
  75. ai_lib_python/types/events.py +343 -0
  76. ai_lib_python/types/message.py +332 -0
  77. ai_lib_python/types/tool.py +191 -0
  78. ai_lib_python/utils/__init__.py +21 -0
  79. ai_lib_python/utils/tool_call_assembler.py +317 -0
  80. ai_lib_python-0.5.0.dist-info/METADATA +837 -0
  81. ai_lib_python-0.5.0.dist-info/RECORD +84 -0
  82. ai_lib_python-0.5.0.dist-info/WHEEL +4 -0
  83. ai_lib_python-0.5.0.dist-info/licenses/LICENSE-APACHE +201 -0
  84. ai_lib_python-0.5.0.dist-info/licenses/LICENSE-MIT +21 -0
@@ -0,0 +1,475 @@
1
+ """
2
+ High-level validators for content safety and compliance.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from ai_lib_python.guardrails.base import (
10
+ CompositeGuardrail,
11
+ Guardrail,
12
+ GuardrailResult,
13
+ GuardrailSeverity,
14
+ )
15
+ from ai_lib_python.guardrails.filters import (
16
+ EmailFilter,
17
+ KeywordFilter,
18
+ LengthFilter,
19
+ ProfanityFilter,
20
+ RegexFilter,
21
+ UrlFilter,
22
+ )
23
+
24
+ if TYPE_CHECKING:
25
+ from collections.abc import Sequence
26
+
27
+
28
+ class ContentValidator:
29
+ """High-level content validator with pre-configured guardrails.
30
+
31
+ Provides ready-to-use validators for common use cases.
32
+
33
+ Example:
34
+ >>> validator = ContentValidator.create_input_validator()
35
+ >>> result = validator.check("User input here")
36
+ >>> if not result.is_safe:
37
+ ... print(f"Violations: {[v.message for v in result.violations]}")
38
+ >>>
39
+ >>> # Filter content
40
+ >>> filtered = validator.filter("Input with sensitive data")
41
+ """
42
+
43
+ def __init__(self, guardrails: Sequence[Guardrail]) -> None:
44
+ """Initialize content validator.
45
+
46
+ Args:
47
+ guardrails: List of guardrails to apply
48
+ """
49
+ self._composite = CompositeGuardrail(
50
+ rule_id="content-validator",
51
+ guardrails=list(guardrails),
52
+ severity=GuardrailSeverity.WARNING,
53
+ stop_on_first=False,
54
+ )
55
+
56
+ def check(self, content: str) -> GuardrailResult:
57
+ """Check content against all guardrails.
58
+
59
+ Args:
60
+ content: Text content to validate
61
+
62
+ Returns:
63
+ GuardrailResult with all violations
64
+ """
65
+ return self._composite.check(content)
66
+
67
+ def filter(self, content: str) -> str:
68
+ """Filter content by applying all guardrails.
69
+
70
+ Args:
71
+ content: Text content to filter
72
+
73
+ Returns:
74
+ Filtered content
75
+ """
76
+ return self._composite.filter(content)
77
+
78
+ def add_guardrail(self, guardrail: Guardrail) -> None:
79
+ """Add a guardrail to the validator."""
80
+ self._composite.add_guardrail(guardrail)
81
+
82
+ def remove_guardrail(self, rule_id: str) -> bool:
83
+ """Remove a guardrail by rule ID."""
84
+ return self._composite.remove_guardrail(rule_id)
85
+
86
+ @classmethod
87
+ def create_input_validator(
88
+ cls,
89
+ severity: GuardrailSeverity = GuardrailSeverity.WARNING,
90
+ ) -> "ContentValidator":
91
+ """Create a validator for user input.
92
+
93
+ Filters for common input issues:
94
+ - Length limits
95
+ - Profanity
96
+ - URLs
97
+ - Emails
98
+
99
+ Args:
100
+ severity: Severity level for violations
101
+
102
+ Returns:
103
+ Configured ContentValidator
104
+ """
105
+ guardrails = [
106
+ LengthFilter(
107
+ rule_id="input-length",
108
+ min_length=1,
109
+ max_length=10000,
110
+ severity=severity,
111
+ count_mode="chars",
112
+ ),
113
+ ProfanityFilter(
114
+ rule_id="input-profanity",
115
+ severity=severity,
116
+ ),
117
+ UrlFilter(
118
+ rule_id="input-urls",
119
+ action="allow",
120
+ severity=severity,
121
+ allowed_domains=["example.com"], # Add your allowed domains
122
+ ),
123
+ EmailFilter(
124
+ rule_id="input-emails",
125
+ action="allow",
126
+ severity=severity,
127
+ allowed_domains=["example.com"], # Add your allowed domains
128
+ ),
129
+ ]
130
+
131
+ return cls(guardrails)
132
+
133
+ @classmethod
134
+ def create_output_validator(
135
+ cls,
136
+ severity: GuardrailSeverity = GuardrailSeverity.WARNING,
137
+ ) -> "ContentValidator":
138
+ """Create a validator for AI model output.
139
+
140
+ Filters for common output issues:
141
+ - Excessive length
142
+ - Profanity
143
+ - Malicious URLs
144
+ - PII patterns
145
+
146
+ Args:
147
+ severity: Severity level for violations
148
+
149
+ Returns:
150
+ Configured ContentValidator
151
+ """
152
+ guardrails = [
153
+ LengthFilter(
154
+ rule_id="output-length",
155
+ min_length=1,
156
+ max_length=50000,
157
+ severity=severity,
158
+ count_mode="chars",
159
+ ),
160
+ ProfanityFilter(
161
+ rule_id="output-profanity",
162
+ severity=severity,
163
+ ),
164
+ UrlFilter(
165
+ rule_id="output-urls",
166
+ action="deny",
167
+ severity=severity,
168
+ blocked_domains=["malicious.example.com", "spam.example.com"],
169
+ ),
170
+ # Block common PII patterns
171
+ RegexFilter(
172
+ rule_id="output-credit-card",
173
+ pattern=r"\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b",
174
+ severity=GuardrailSeverity.CRITICAL,
175
+ replacement="[CARD REDECTED]",
176
+ ),
177
+ RegexFilter(
178
+ rule_id="output-ssn",
179
+ pattern=r"\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b",
180
+ severity=GuardrailSeverity.CRITICAL,
181
+ replacement="[SSN REDECTED]",
182
+ ),
183
+ ]
184
+
185
+ return cls(guardrails)
186
+
187
+ @classmethod
188
+ def create_pii_validator(
189
+ cls,
190
+ severity: GuardrailSeverity = GuardrailSeverity.CRITICAL,
191
+ ) -> "ContentValidator":
192
+ """Create a validator focusing on PII detection.
193
+
194
+ Detects and blocks Personally Identifiable Information.
195
+
196
+ Args:
197
+ severity: Severity level for violations
198
+
199
+ Returns:
200
+ Configured ContentValidator
201
+ """
202
+ guardrails = [
203
+ # Email addresses
204
+ EmailFilter(
205
+ rule_id="pii-email",
206
+ action="block",
207
+ severity=severity,
208
+ ),
209
+ # Phone numbers (various formats)
210
+ RegexFilter(
211
+ rule_id="pii-phone",
212
+ pattern=r"\b\d{3}[-\s.]?\d{3}[-\s.]?\d{4}\b",
213
+ severity=severity,
214
+ replacement="[PHONE REDACTED]",
215
+ ),
216
+ # Credit card numbers
217
+ RegexFilter(
218
+ rule_id="pii-credit-card",
219
+ pattern=r"\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b",
220
+ severity=severity,
221
+ replacement="[CARD REDACTED]",
222
+ ),
223
+ # Social Security Number
224
+ RegexFilter(
225
+ rule_id="pii-ssn",
226
+ pattern=r"\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b",
227
+ severity=severity,
228
+ replacement="[SSN REDACTED]",
229
+ ),
230
+ # IP addresses
231
+ RegexFilter(
232
+ rule_id="pii-ip",
233
+ pattern=r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",
234
+ severity=severity,
235
+ replacement="[IP REDACTED]",
236
+ ),
237
+ ]
238
+
239
+ return cls(guardrails)
240
+
241
+ @classmethod
242
+ def create_custom_validator(
243
+ cls,
244
+ forbidden_keywords: list[str] | None = None,
245
+ allowed_domains: list[str] | None = None,
246
+ max_length: int | None = None,
247
+ severity: GuardrailSeverity = GuardrailSeverity.WARNING,
248
+ ) -> "ContentValidator":
249
+ """Create a custom validator with specific rules.
250
+
251
+ Args:
252
+ forbidden_keywords: List of keywords to block
253
+ allowed_domains: List of allowed URL/email domains
254
+ max_length: Maximum content length
255
+ severity: Severity level for violations
256
+
257
+ Returns:
258
+ Configured ContentValidator
259
+ """
260
+ guardrails = []
261
+
262
+ if forbidden_keywords:
263
+ guardrails.append(
264
+ KeywordFilter(
265
+ rule_id="custom-keywords",
266
+ keywords=forbidden_keywords,
267
+ severity=severity,
268
+ )
269
+ )
270
+
271
+ if allowed_domains:
272
+ guardrails.extend([
273
+ UrlFilter(
274
+ rule_id="custom-urls",
275
+ action="allow",
276
+ severity=severity,
277
+ allowed_domains=allowed_domains,
278
+ ),
279
+ EmailFilter(
280
+ rule_id="custom-emails",
281
+ action="allow",
282
+ severity=severity,
283
+ allowed_domains=allowed_domains,
284
+ ),
285
+ ])
286
+
287
+ if max_length:
288
+ guardrails.append(
289
+ LengthFilter(
290
+ rule_id="custom-length",
291
+ max_length=max_length,
292
+ severity=severity,
293
+ )
294
+ )
295
+
296
+ return cls(guardrails)
297
+
298
+ @classmethod
299
+ def create_code_validator(
300
+ cls,
301
+ severity: GuardrailSeverity = GuardrailSeverity.INFO,
302
+ ) -> "ContentValidator":
303
+ """Create a validator for code snippets.
304
+
305
+ Less strict validation suitable for code-related content.
306
+
307
+ Args:
308
+ severity: Severity level for violations
309
+
310
+ Returns:
311
+ Configured ContentValidator
312
+ """
313
+ guardrails = [
314
+ # Allow URLs (useful for code examples)
315
+ UrlFilter(
316
+ rule_id="code-urls",
317
+ action="allow",
318
+ severity=severity,
319
+ allowed_domains=[], # Allow all domains
320
+ ),
321
+ # Allow emails (common in code)
322
+ EmailFilter(
323
+ rule_id="code-emails",
324
+ action="allow",
325
+ severity=severity,
326
+ allowed_domains=[], # Allow all domains
327
+ ),
328
+ # Length limit for code snippets
329
+ LengthFilter(
330
+ rule_id="code-length",
331
+ min_length=1,
332
+ max_length=100000,
333
+ severity=severity,
334
+ count_mode="chars",
335
+ ),
336
+ ]
337
+
338
+ return cls(guardrails)
339
+
340
+
341
+ class SafetyValidator(ContentValidator):
342
+ """Validator focused specifically on content safety.
343
+
344
+ Detects potentially harmful or inappropriate content.
345
+
346
+ Example:
347
+ >>> validator = SafetyValidator()
348
+ >>> result = validator.check("Input to check")
349
+ >>> if not result.is_safe:
350
+ ... print("Content flagged as unsafe")
351
+ """
352
+
353
+ # Potentially harmful keywords
354
+ _HARMFUL_KEYWORDS = [
355
+ "bomb", "drug", "weapon", "kill",
356
+ "illegal", "hack", "steal",
357
+ ]
358
+
359
+ # Self-harm indicators
360
+ _SELF_HARM_KEYWORDS = [
361
+ "suicide", "end it all", "kill myself",
362
+ "want to die", "don't want to live",
363
+ ]
364
+
365
+ def __init__(
366
+ self,
367
+ severity: GuardrailSeverity = GuardrailSeverity.CRITICAL,
368
+ block_self_harm: bool = True,
369
+ block_harmful: bool = True,
370
+ block_profane: bool = True,
371
+ ) -> None:
372
+ """Initialize safety validator.
373
+
374
+ Args:
375
+ severity: Severity level for violations
376
+ block_self_harm: Block self-harm related content
377
+ block_harmful: Block harmful content
378
+ block_profane: Block profane content
379
+ """
380
+ guardrails = []
381
+
382
+ if block_self_harm:
383
+ guardrails.append(
384
+ KeywordFilter(
385
+ rule_id="safety-self-harm",
386
+ keywords=self._SELF_HARM_KEYWORDS,
387
+ severity=severity,
388
+ case_sensitive=False,
389
+ )
390
+ )
391
+
392
+ if block_harmful:
393
+ guardrails.append(
394
+ KeywordFilter(
395
+ rule_id="safety-harmful",
396
+ keywords=self._HARMFUL_KEYWORDS,
397
+ severity=severity,
398
+ case_sensitive=False,
399
+ )
400
+ )
401
+
402
+ if block_profane:
403
+ guardrails.append(
404
+ ProfanityFilter(
405
+ rule_id="safety-profanity",
406
+ severity=severity,
407
+ )
408
+ )
409
+
410
+ super().__init__(guardrails)
411
+
412
+
413
+ class ComplianceValidator(ContentValidator):
414
+ """Validator for regulatory compliance.
415
+
416
+ Helps enforce compliance with data protection regulations.
417
+
418
+ Example:
419
+ >>> validator = ComplianceValidator(
420
+ ... gdpr_mode=True,
421
+ ... hipaa_mode=False,
422
+ ... )
423
+ >>> result = validator.check("Content to check")
424
+ """
425
+
426
+ PII_PATTERNS = {
427
+ "email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
428
+ "phone": r"\b\d{3}[-\s.]?\d{3}[-\s.]?\d{4}\b",
429
+ "ssn": r"\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b",
430
+ "credit_card": r"\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b",
431
+ "ip_address": r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",
432
+ }
433
+
434
+ def __init__(
435
+ self,
436
+ gdpr_mode: bool = True,
437
+ hipaa_mode: bool = False,
438
+ severity: GuardrailSeverity = GuardrailSeverity.CRITICAL,
439
+ ) -> None:
440
+ """Initialize compliance validator.
441
+
442
+ Args:
443
+ gdpr_mode: Enable GDPR compliance (detect PII)
444
+ hipaa_mode: Enable HIPAA compliance (detect PHI)
445
+ severity: Severity level for violations
446
+ """
447
+ guardrails = []
448
+
449
+ if gdpr_mode:
450
+ # GDPR: Detect and block PII
451
+ for name, pattern in self.PII_PATTERNS.items():
452
+ guardrails.append(
453
+ RegexFilter(
454
+ rule_id=f"gdpr-{name}",
455
+ pattern=pattern,
456
+ severity=severity,
457
+ replacement=f"[{name.upper()} REDACTED]",
458
+ message=f"GDPR violation: {name} detected",
459
+ )
460
+ )
461
+
462
+ if hipaa_mode:
463
+ # HIPAA: Additional protected health information patterns
464
+ # (Additional patterns can be added based on requirements)
465
+ guardrails.extend([
466
+ RegexFilter(
467
+ rule_id="hipaa-medical-record",
468
+ pattern=r"\bMR[A-Z]?\d{6,}\b",
469
+ severity=severity,
470
+ replacement="[MRN REDACTED]",
471
+ message="HIPAA violation: Medical record number detected",
472
+ ),
473
+ ])
474
+
475
+ super().__init__(guardrails)
@@ -0,0 +1,55 @@
1
+ """
2
+ Pipeline layer - Stream processing operators.
3
+
4
+ This module implements the operator pipeline for processing streaming responses:
5
+ - Decoder: Parses raw bytes into frames (SSE, JSON Lines)
6
+ - Selector: Filters frames using JSONPath expressions
7
+ - Accumulator: Accumulates stateful data (tool call arguments)
8
+ - EventMapper: Converts frames to unified streaming events
9
+ - FanOut: Expands arrays into separate events
10
+
11
+ The pipeline is constructed dynamically from protocol manifests.
12
+ """
13
+
14
+ from ai_lib_python.pipeline.accumulate import ToolCallAccumulator
15
+ from ai_lib_python.pipeline.base import Decoder, EventMapper, Pipeline, Transform
16
+ from ai_lib_python.pipeline.decode import (
17
+ AnthropicSSEDecoder,
18
+ JsonLinesDecoder,
19
+ SSEDecoder,
20
+ )
21
+ from ai_lib_python.pipeline.event_map import (
22
+ AnthropicEventMapper,
23
+ DefaultEventMapper,
24
+ ProtocolEventMapper,
25
+ )
26
+ from ai_lib_python.pipeline.fan_out import (
27
+ FanOutTransform,
28
+ ReplicateTransform,
29
+ SplitTransform,
30
+ create_fan_out,
31
+ )
32
+ from ai_lib_python.pipeline.select import JsonPathSelector, PassThroughSelector
33
+
34
+ __all__ = [
35
+ # Base abstractions
36
+ "AnthropicEventMapper",
37
+ "AnthropicSSEDecoder",
38
+ "Decoder",
39
+ "DefaultEventMapper",
40
+ "EventMapper",
41
+ # FanOut
42
+ "FanOutTransform",
43
+ # Implementations
44
+ "JsonLinesDecoder",
45
+ "JsonPathSelector",
46
+ "PassThroughSelector",
47
+ "Pipeline",
48
+ "ProtocolEventMapper",
49
+ "ReplicateTransform",
50
+ "SSEDecoder",
51
+ "SplitTransform",
52
+ "ToolCallAccumulator",
53
+ "Transform",
54
+ "create_fan_out",
55
+ ]