raxe 0.4.6__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.
- raxe/__init__.py +101 -0
- raxe/application/__init__.py +48 -0
- raxe/application/ab_testing.py +170 -0
- raxe/application/analytics/__init__.py +30 -0
- raxe/application/analytics/achievement_service.py +444 -0
- raxe/application/analytics/repositories.py +172 -0
- raxe/application/analytics/retention_service.py +267 -0
- raxe/application/analytics/statistics_service.py +419 -0
- raxe/application/analytics/streak_service.py +283 -0
- raxe/application/apply_policy.py +291 -0
- raxe/application/eager_l2.py +503 -0
- raxe/application/preloader.py +353 -0
- raxe/application/scan_merger.py +321 -0
- raxe/application/scan_pipeline.py +1059 -0
- raxe/application/scan_pipeline_async.py +403 -0
- raxe/application/session_tracker.py +458 -0
- raxe/application/telemetry_manager.py +357 -0
- raxe/application/telemetry_orchestrator.py +1210 -0
- raxe/async_sdk/__init__.py +34 -0
- raxe/async_sdk/cache.py +286 -0
- raxe/async_sdk/client.py +556 -0
- raxe/async_sdk/wrappers/__init__.py +23 -0
- raxe/async_sdk/wrappers/openai.py +238 -0
- raxe/cli/__init__.py +21 -0
- raxe/cli/auth.py +1047 -0
- raxe/cli/branding.py +235 -0
- raxe/cli/config.py +334 -0
- raxe/cli/custom_rules.py +458 -0
- raxe/cli/doctor.py +686 -0
- raxe/cli/error_handler.py +665 -0
- raxe/cli/event.py +648 -0
- raxe/cli/exit_codes.py +57 -0
- raxe/cli/expiry_warning.py +302 -0
- raxe/cli/export.py +183 -0
- raxe/cli/history.py +247 -0
- raxe/cli/l2_formatter.py +872 -0
- raxe/cli/main.py +1137 -0
- raxe/cli/models.py +590 -0
- raxe/cli/output.py +403 -0
- raxe/cli/privacy.py +84 -0
- raxe/cli/profiler.py +262 -0
- raxe/cli/progress.py +379 -0
- raxe/cli/progress_context.py +101 -0
- raxe/cli/repl.py +394 -0
- raxe/cli/rules.py +542 -0
- raxe/cli/setup_wizard.py +721 -0
- raxe/cli/stats.py +292 -0
- raxe/cli/suppress.py +501 -0
- raxe/cli/telemetry.py +1384 -0
- raxe/cli/test.py +130 -0
- raxe/cli/tune.py +315 -0
- raxe/cli/validate.py +218 -0
- raxe/domain/__init__.py +30 -0
- raxe/domain/analytics/__init__.py +97 -0
- raxe/domain/analytics/achievements.py +306 -0
- raxe/domain/analytics/models.py +120 -0
- raxe/domain/analytics/retention.py +168 -0
- raxe/domain/analytics/statistics.py +207 -0
- raxe/domain/analytics/streaks.py +173 -0
- raxe/domain/engine/__init__.py +15 -0
- raxe/domain/engine/executor.py +396 -0
- raxe/domain/engine/matcher.py +212 -0
- raxe/domain/inline_suppression.py +176 -0
- raxe/domain/ml/__init__.py +133 -0
- raxe/domain/ml/embedding_cache.py +309 -0
- raxe/domain/ml/gemma_detector.py +921 -0
- raxe/domain/ml/gemma_models.py +346 -0
- raxe/domain/ml/l2_config.py +428 -0
- raxe/domain/ml/l2_output_schema.py +443 -0
- raxe/domain/ml/manifest_loader.py +309 -0
- raxe/domain/ml/manifest_schema.py +345 -0
- raxe/domain/ml/model_metadata.py +263 -0
- raxe/domain/ml/model_registry.py +786 -0
- raxe/domain/ml/protocol.py +282 -0
- raxe/domain/ml/scoring_models.py +419 -0
- raxe/domain/ml/stub_detector.py +397 -0
- raxe/domain/ml/threat_scorer.py +757 -0
- raxe/domain/ml/tokenizer_registry.py +372 -0
- raxe/domain/ml/voting/__init__.py +89 -0
- raxe/domain/ml/voting/config.py +595 -0
- raxe/domain/ml/voting/engine.py +465 -0
- raxe/domain/ml/voting/head_voters.py +378 -0
- raxe/domain/ml/voting/models.py +222 -0
- raxe/domain/models.py +82 -0
- raxe/domain/packs/__init__.py +17 -0
- raxe/domain/packs/models.py +304 -0
- raxe/domain/policies/__init__.py +20 -0
- raxe/domain/policies/evaluator.py +212 -0
- raxe/domain/policies/models.py +223 -0
- raxe/domain/rules/__init__.py +32 -0
- raxe/domain/rules/custom.py +286 -0
- raxe/domain/rules/models.py +273 -0
- raxe/domain/rules/schema.py +166 -0
- raxe/domain/rules/validator.py +556 -0
- raxe/domain/suppression.py +801 -0
- raxe/domain/suppression_factory.py +174 -0
- raxe/domain/telemetry/__init__.py +116 -0
- raxe/domain/telemetry/backpressure.py +424 -0
- raxe/domain/telemetry/event_creator.py +362 -0
- raxe/domain/telemetry/events.py +1282 -0
- raxe/domain/telemetry/priority.py +263 -0
- raxe/domain/telemetry/scan_telemetry_builder.py +670 -0
- raxe/infrastructure/__init__.py +25 -0
- raxe/infrastructure/analytics/__init__.py +18 -0
- raxe/infrastructure/analytics/aggregator.py +484 -0
- raxe/infrastructure/analytics/aggregator_optimized.py +184 -0
- raxe/infrastructure/analytics/engine.py +748 -0
- raxe/infrastructure/analytics/repository.py +409 -0
- raxe/infrastructure/analytics/streaks.py +467 -0
- raxe/infrastructure/analytics/views.py +178 -0
- raxe/infrastructure/cloud/__init__.py +9 -0
- raxe/infrastructure/config/__init__.py +56 -0
- raxe/infrastructure/config/endpoints.py +641 -0
- raxe/infrastructure/config/scan_config.py +352 -0
- raxe/infrastructure/config/yaml_config.py +459 -0
- raxe/infrastructure/database/__init__.py +10 -0
- raxe/infrastructure/database/connection.py +200 -0
- raxe/infrastructure/database/models.py +325 -0
- raxe/infrastructure/database/scan_history.py +764 -0
- raxe/infrastructure/ml/__init__.py +0 -0
- raxe/infrastructure/ml/download_progress.py +438 -0
- raxe/infrastructure/ml/model_downloader.py +457 -0
- raxe/infrastructure/models/__init__.py +16 -0
- raxe/infrastructure/models/discovery.py +461 -0
- raxe/infrastructure/packs/__init__.py +13 -0
- raxe/infrastructure/packs/loader.py +407 -0
- raxe/infrastructure/packs/registry.py +381 -0
- raxe/infrastructure/policies/__init__.py +16 -0
- raxe/infrastructure/policies/api_client.py +256 -0
- raxe/infrastructure/policies/validator.py +227 -0
- raxe/infrastructure/policies/yaml_loader.py +250 -0
- raxe/infrastructure/rules/__init__.py +18 -0
- raxe/infrastructure/rules/custom_loader.py +224 -0
- raxe/infrastructure/rules/versioning.py +222 -0
- raxe/infrastructure/rules/yaml_loader.py +286 -0
- raxe/infrastructure/security/__init__.py +31 -0
- raxe/infrastructure/security/auth.py +145 -0
- raxe/infrastructure/security/policy_validator.py +124 -0
- raxe/infrastructure/security/signatures.py +171 -0
- raxe/infrastructure/suppression/__init__.py +36 -0
- raxe/infrastructure/suppression/composite_repository.py +154 -0
- raxe/infrastructure/suppression/sqlite_repository.py +231 -0
- raxe/infrastructure/suppression/yaml_composite_repository.py +156 -0
- raxe/infrastructure/suppression/yaml_repository.py +510 -0
- raxe/infrastructure/telemetry/__init__.py +79 -0
- raxe/infrastructure/telemetry/acquisition.py +179 -0
- raxe/infrastructure/telemetry/config.py +254 -0
- raxe/infrastructure/telemetry/credential_store.py +947 -0
- raxe/infrastructure/telemetry/dual_queue.py +1123 -0
- raxe/infrastructure/telemetry/flush_helper.py +343 -0
- raxe/infrastructure/telemetry/flush_scheduler.py +776 -0
- raxe/infrastructure/telemetry/health_client.py +394 -0
- raxe/infrastructure/telemetry/hook.py +347 -0
- raxe/infrastructure/telemetry/queue.py +520 -0
- raxe/infrastructure/telemetry/sender.py +476 -0
- raxe/infrastructure/tracking/__init__.py +13 -0
- raxe/infrastructure/tracking/usage.py +389 -0
- raxe/integrations/__init__.py +55 -0
- raxe/integrations/availability.py +143 -0
- raxe/integrations/registry.py +122 -0
- raxe/integrations/utils.py +135 -0
- raxe/mcp/__init__.py +62 -0
- raxe/mcp/cli.py +97 -0
- raxe/mcp/server.py +409 -0
- raxe/monitoring/__init__.py +51 -0
- raxe/monitoring/metrics.py +372 -0
- raxe/monitoring/profiler.py +388 -0
- raxe/monitoring/server.py +136 -0
- raxe/packs/core/v1.0.0/pack.yaml +1394 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-001@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-006@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-014@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-017@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-022@1.0.0.yaml +67 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-023@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-024@1.0.0.yaml +80 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-025@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-026@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-027@1.0.0.yaml +77 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-028@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-029@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-030@1.0.0.yaml +55 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-033@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-035@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-046@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-047@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-048@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-049@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-050@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-068@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-078@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2001@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2004@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-201@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-202@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-203@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3007@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3016@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3027@1.0.0.yaml +64 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3028@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3029@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3030@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3031@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3032@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3033@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-007@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-015@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-017@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-022@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-023@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-025@1.0.0.yaml +93 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-026@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-027@1.0.0.yaml +82 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-028@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-033@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-036@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-037@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-052@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-054@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-056@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-065@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-075@1.0.0.yaml +45 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-079@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1080@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1090@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1104@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1105@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1112@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-201@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-202@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-203@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-204@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-205@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-206@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-207@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-208@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-209@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-210@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-211@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-212@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-213@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-214@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-215@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-216@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-217@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-218@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-219@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-220@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-221@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-222@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-223@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-224@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-225@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-226@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-227@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-228@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-229@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-230@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-231@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-232@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-233@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-234@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-235@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-236@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-237@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-238@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-013@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-019@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-029@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-038@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-044@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-067@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-069@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-100@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-101@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-102@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-103@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-104@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-105@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-106@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-107@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-108@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-109@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-110@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-111@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-201@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-203@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3004@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3006@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3011@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-5016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6001@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-70@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-71@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-72@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-73@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-74@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-75@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-76@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-77@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-78@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-99@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-001@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-002@1.0.0.yaml +71 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-003@1.0.0.yaml +65 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-004@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-101@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-102@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-104@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-105@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-106@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-107@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-108@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-109@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-111@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-112@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-113@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-114@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-115@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-116@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-117@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-118@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-119@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-120@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-121@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-122@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-123@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-124@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-125@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-126@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-127@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-128@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-129@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-130@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-131@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-132@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-133@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-134@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-135@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-136@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-137@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-138@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-139@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-140@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-141@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-142@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-143@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-144@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-145@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-146@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-147@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-148@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-149@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-150@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-151@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-152@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-153@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-154@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-155@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-156@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-157@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-158@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-159@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-160@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-161@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-001@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-009@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-028@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-033@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-034@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-039@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-066@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-076@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-098@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-104@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-105@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-111@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-121@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-122@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-123@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-124@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-125@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-126@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-127@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-128@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-129@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-130@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-131@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-132@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-133@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-134@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-135@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-136@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-137@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-138@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-139@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-140@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-141@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-142@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-143@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-144@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-145@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-146@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-147@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-148@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-149@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-150@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-151@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-152@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-153@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-154@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-155@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-156@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-157@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-158@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-159@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-160@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-161@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-162@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-201@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-203@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-204@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-205@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-206@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-207@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-009@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-012@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-017@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-025@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-027@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-034@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-037@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-040@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-041@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-050@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-051@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-052@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-053@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-054@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-055@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-056@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-058@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2015@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2025@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2035@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2037@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2042@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3001@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3003@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3004@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3005@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3006@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3007@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3008@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3009@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3010@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3011@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3012@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3013@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3014@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3015@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3016@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3017@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3018@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3019@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3020@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3021@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3022@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3023@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3024@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3025@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3026@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3027@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3028@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3029@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3030@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3031@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3032@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3033@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3034@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3035@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3037@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3038@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3039@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3040@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3041@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3042@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3043@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3044@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3045@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3046@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3047@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3048@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3049@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3050@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3051@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3052@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3053@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3054@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3055@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3057@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3058@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3059@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3060@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3061@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3062@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3063@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3064@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3065@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3066@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3067@1.0.0.yaml +88 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3068@1.0.0.yaml +94 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3069@1.0.0.yaml +90 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3070@1.0.0.yaml +99 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3071@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3072@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3073@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3074@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3075@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3076@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3077@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3078@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3079@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3080@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3081@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3082@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3083@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3084@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3085@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-016@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-042@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-045@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-050@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-201@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3001@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3006@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3009@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3012@1.0.0.yaml +41 -0
- raxe/plugins/__init__.py +98 -0
- raxe/plugins/custom_rules.py +380 -0
- raxe/plugins/loader.py +389 -0
- raxe/plugins/manager.py +538 -0
- raxe/plugins/protocol.py +428 -0
- raxe/py.typed +0 -0
- raxe/sdk/__init__.py +77 -0
- raxe/sdk/agent_scanner.py +1918 -0
- raxe/sdk/client.py +1603 -0
- raxe/sdk/decorator.py +175 -0
- raxe/sdk/exceptions.py +859 -0
- raxe/sdk/integrations/__init__.py +277 -0
- raxe/sdk/integrations/agent_scanner.py +71 -0
- raxe/sdk/integrations/autogen.py +872 -0
- raxe/sdk/integrations/crewai.py +1368 -0
- raxe/sdk/integrations/dspy.py +845 -0
- raxe/sdk/integrations/extractors.py +363 -0
- raxe/sdk/integrations/huggingface.py +395 -0
- raxe/sdk/integrations/langchain.py +948 -0
- raxe/sdk/integrations/litellm.py +484 -0
- raxe/sdk/integrations/llamaindex.py +1049 -0
- raxe/sdk/integrations/portkey.py +831 -0
- raxe/sdk/suppression_context.py +215 -0
- raxe/sdk/wrappers/__init__.py +163 -0
- raxe/sdk/wrappers/anthropic.py +310 -0
- raxe/sdk/wrappers/openai.py +221 -0
- raxe/sdk/wrappers/vertexai.py +484 -0
- raxe/utils/__init__.py +12 -0
- raxe/utils/error_sanitizer.py +135 -0
- raxe/utils/logging.py +241 -0
- raxe/utils/performance.py +414 -0
- raxe/utils/profiler.py +339 -0
- raxe/utils/validators.py +170 -0
- raxe-0.4.6.dist-info/METADATA +471 -0
- raxe-0.4.6.dist-info/RECORD +668 -0
- raxe-0.4.6.dist-info/WHEEL +5 -0
- raxe-0.4.6.dist-info/entry_points.txt +2 -0
- raxe-0.4.6.dist-info/licenses/LICENSE +56 -0
- raxe-0.4.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,948 @@
|
|
|
1
|
+
"""LangChain integration for RAXE scanning.
|
|
2
|
+
|
|
3
|
+
Provides a callback handler that automatically scans prompts and responses
|
|
4
|
+
in LangChain applications without modifying existing code.
|
|
5
|
+
|
|
6
|
+
This integration supports:
|
|
7
|
+
- LangChain 0.1.x, 0.2.x, 0.3.x
|
|
8
|
+
- LLMs, Chat Models
|
|
9
|
+
- Chains (Sequential, Conversational, etc.)
|
|
10
|
+
- Agents and Tools (with validation)
|
|
11
|
+
- Memory systems
|
|
12
|
+
|
|
13
|
+
Key Features:
|
|
14
|
+
- AgentScanner composition for unified scanning
|
|
15
|
+
- Tool validation with allowlist/blocklist
|
|
16
|
+
- Trace-aware scanning with correlation IDs
|
|
17
|
+
- Version-compatible callback implementation
|
|
18
|
+
- Default: log-only (non-blocking)
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
from langchain.llms import OpenAI
|
|
22
|
+
from raxe.sdk.integrations import RaxeCallbackHandler
|
|
23
|
+
|
|
24
|
+
# Basic usage (log-only mode)
|
|
25
|
+
llm = OpenAI(callbacks=[RaxeCallbackHandler()])
|
|
26
|
+
|
|
27
|
+
# With tool restrictions
|
|
28
|
+
from raxe.sdk.agent_scanner import ToolPolicy
|
|
29
|
+
|
|
30
|
+
handler = RaxeCallbackHandler(
|
|
31
|
+
tool_policy=ToolPolicy.block_tools("shell", "file_write")
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Blocking mode for prompts
|
|
35
|
+
handler = RaxeCallbackHandler(block_on_prompt_threats=True)
|
|
36
|
+
"""
|
|
37
|
+
from __future__ import annotations
|
|
38
|
+
|
|
39
|
+
import logging
|
|
40
|
+
import uuid
|
|
41
|
+
from typing import TYPE_CHECKING, Any
|
|
42
|
+
|
|
43
|
+
from raxe.sdk.agent_scanner import (
|
|
44
|
+
AgentScanner,
|
|
45
|
+
AgentScannerConfig,
|
|
46
|
+
AgentScanResult,
|
|
47
|
+
ScanConfig,
|
|
48
|
+
ScanType,
|
|
49
|
+
ToolPolicy,
|
|
50
|
+
create_agent_scanner,
|
|
51
|
+
)
|
|
52
|
+
from raxe.sdk.client import Raxe
|
|
53
|
+
from raxe.sdk.exceptions import SecurityException
|
|
54
|
+
from raxe.sdk.integrations.extractors import (
|
|
55
|
+
extract_text_from_message,
|
|
56
|
+
extract_text_from_response,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if TYPE_CHECKING:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
logger = logging.getLogger(__name__)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# ============================================================================
|
|
66
|
+
# LangChain Version Detection
|
|
67
|
+
# ============================================================================
|
|
68
|
+
|
|
69
|
+
def _detect_langchain_version() -> tuple[int, int, int]:
|
|
70
|
+
"""Detect installed LangChain version.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Tuple of (major, minor, patch) version numbers.
|
|
74
|
+
Returns (0, 0, 0) if LangChain is not installed.
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
import langchain
|
|
78
|
+
|
|
79
|
+
version_str = getattr(langchain, "__version__", "0.0.0")
|
|
80
|
+
parts = version_str.split(".")
|
|
81
|
+
major = int(parts[0]) if len(parts) > 0 else 0
|
|
82
|
+
minor = int(parts[1]) if len(parts) > 1 else 0
|
|
83
|
+
patch = int(parts[2].split("-")[0].split("a")[0].split("b")[0]) if len(parts) > 2 else 0
|
|
84
|
+
return (major, minor, patch)
|
|
85
|
+
except ImportError:
|
|
86
|
+
return (0, 0, 0)
|
|
87
|
+
except (ValueError, IndexError):
|
|
88
|
+
return (0, 0, 0)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _get_langchain_version_info() -> dict[str, Any]:
|
|
92
|
+
"""Get detailed LangChain version information.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Dictionary with version details for debugging.
|
|
96
|
+
"""
|
|
97
|
+
version = _detect_langchain_version()
|
|
98
|
+
return {
|
|
99
|
+
"version": f"{version[0]}.{version[1]}.{version[2]}",
|
|
100
|
+
"major": version[0],
|
|
101
|
+
"minor": version[1],
|
|
102
|
+
"patch": version[2],
|
|
103
|
+
"has_langchain_core": _has_langchain_core(),
|
|
104
|
+
"has_run_manager": _has_run_manager(),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _has_langchain_core() -> bool:
|
|
109
|
+
"""Check if langchain-core is available."""
|
|
110
|
+
try:
|
|
111
|
+
import langchain_core # noqa: F401
|
|
112
|
+
return True
|
|
113
|
+
except ImportError:
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _has_run_manager() -> bool:
|
|
118
|
+
"""Check if RunManager is available (0.1+)."""
|
|
119
|
+
try:
|
|
120
|
+
from langchain_core.callbacks.manager import RunManager # noqa: F401
|
|
121
|
+
return True
|
|
122
|
+
except ImportError:
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _get_base_callback_handler_class():
|
|
127
|
+
"""Get BaseCallbackHandler class from langchain.
|
|
128
|
+
|
|
129
|
+
This function is called at class instantiation time, not import time,
|
|
130
|
+
ensuring proper inheritance even if langchain is installed later.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
BaseCallbackHandler class or object as fallback
|
|
134
|
+
"""
|
|
135
|
+
try:
|
|
136
|
+
from langchain_core.callbacks import BaseCallbackHandler
|
|
137
|
+
return BaseCallbackHandler
|
|
138
|
+
except ImportError:
|
|
139
|
+
try:
|
|
140
|
+
from langchain.callbacks.base import BaseCallbackHandler
|
|
141
|
+
return BaseCallbackHandler
|
|
142
|
+
except ImportError:
|
|
143
|
+
return object
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ============================================================================
|
|
147
|
+
# Base Callback Handler Implementation
|
|
148
|
+
# ============================================================================
|
|
149
|
+
|
|
150
|
+
class _RaxeCallbackHandlerMixin:
|
|
151
|
+
"""Mixin containing RAXE callback handler logic.
|
|
152
|
+
|
|
153
|
+
This mixin provides all the RAXE scanning functionality and is combined
|
|
154
|
+
with the appropriate LangChain base class at runtime.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
# Class-level version info (computed once)
|
|
158
|
+
_langchain_version: tuple[int, int, int] | None = None
|
|
159
|
+
|
|
160
|
+
def __init__(
|
|
161
|
+
self,
|
|
162
|
+
raxe_client: Raxe | None = None,
|
|
163
|
+
*,
|
|
164
|
+
scanner: AgentScanner | None = None,
|
|
165
|
+
tool_policy: ToolPolicy | None = None,
|
|
166
|
+
block_on_prompt_threats: bool = False,
|
|
167
|
+
block_on_response_threats: bool = False,
|
|
168
|
+
scan_tools: bool = True,
|
|
169
|
+
scan_agent_actions: bool = True,
|
|
170
|
+
on_threat: Any | None = None,
|
|
171
|
+
) -> None:
|
|
172
|
+
"""Initialize RAXE callback handler.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
raxe_client: Optional Raxe instance (creates default if None)
|
|
176
|
+
scanner: Optional AgentScanner instance (creates default if None)
|
|
177
|
+
tool_policy: Policy for tool validation (default: no restrictions)
|
|
178
|
+
block_on_prompt_threats: Block on prompt threats (default: False)
|
|
179
|
+
block_on_response_threats: Block on response threats (default: False)
|
|
180
|
+
scan_tools: Scan tool inputs/outputs (default: True)
|
|
181
|
+
scan_agent_actions: Scan agent actions (default: True)
|
|
182
|
+
on_threat: Optional callback for threat notifications
|
|
183
|
+
"""
|
|
184
|
+
# Store configuration
|
|
185
|
+
self.block_on_prompt_threats = block_on_prompt_threats
|
|
186
|
+
self.block_on_response_threats = block_on_response_threats
|
|
187
|
+
self.scan_tools = scan_tools
|
|
188
|
+
self.scan_agent_actions = scan_agent_actions
|
|
189
|
+
self.on_threat = on_threat
|
|
190
|
+
|
|
191
|
+
# Create or use provided Raxe client
|
|
192
|
+
self._raxe = raxe_client or Raxe()
|
|
193
|
+
|
|
194
|
+
# Create or use provided scanner with config
|
|
195
|
+
if scanner is not None:
|
|
196
|
+
self._scanner = scanner
|
|
197
|
+
else:
|
|
198
|
+
# Use AgentScannerConfig for proper initialization
|
|
199
|
+
config = AgentScannerConfig(
|
|
200
|
+
scan_prompts=True,
|
|
201
|
+
scan_responses=True,
|
|
202
|
+
scan_tool_calls=scan_tools,
|
|
203
|
+
# Default to log-only mode for safety
|
|
204
|
+
on_threat="block" if block_on_prompt_threats else "log",
|
|
205
|
+
)
|
|
206
|
+
self._scanner = create_agent_scanner(
|
|
207
|
+
self._raxe, config, integration_type="langchain"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Trace ID for correlation (set on each chain/agent run)
|
|
211
|
+
self.trace_id: str | None = None
|
|
212
|
+
|
|
213
|
+
# Cache version info
|
|
214
|
+
if _RaxeCallbackHandlerMixin._langchain_version is None:
|
|
215
|
+
_RaxeCallbackHandlerMixin._langchain_version = _detect_langchain_version()
|
|
216
|
+
|
|
217
|
+
logger.debug(
|
|
218
|
+
"RaxeCallbackHandler initialized",
|
|
219
|
+
extra={
|
|
220
|
+
"langchain_version": self._langchain_version,
|
|
221
|
+
"block_on_prompt_threats": block_on_prompt_threats,
|
|
222
|
+
"block_on_response_threats": block_on_response_threats,
|
|
223
|
+
},
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# ========================================================================
|
|
227
|
+
# LLM Callbacks - Core Scanning Points
|
|
228
|
+
# ========================================================================
|
|
229
|
+
|
|
230
|
+
def on_llm_start(
|
|
231
|
+
self,
|
|
232
|
+
serialized: dict[str, Any],
|
|
233
|
+
prompts: list[str],
|
|
234
|
+
*,
|
|
235
|
+
run_id: uuid.UUID | None = None,
|
|
236
|
+
parent_run_id: uuid.UUID | None = None,
|
|
237
|
+
tags: list[str] | None = None,
|
|
238
|
+
metadata: dict[str, Any] | None = None,
|
|
239
|
+
**kwargs: Any,
|
|
240
|
+
) -> Any:
|
|
241
|
+
"""Scan prompts before sending to LLM.
|
|
242
|
+
|
|
243
|
+
This is the primary injection point for prompt scanning.
|
|
244
|
+
Called before each LLM invocation with the prompts.
|
|
245
|
+
"""
|
|
246
|
+
for prompt in prompts:
|
|
247
|
+
result = self._scanner.scan(prompt, scan_type=ScanType.PROMPT)
|
|
248
|
+
|
|
249
|
+
if result.has_threats:
|
|
250
|
+
self._handle_threat(result, "prompt", prompt[:100])
|
|
251
|
+
|
|
252
|
+
if self.block_on_prompt_threats:
|
|
253
|
+
raise SecurityException(result.pipeline_result)
|
|
254
|
+
|
|
255
|
+
def on_llm_end(
|
|
256
|
+
self,
|
|
257
|
+
response: Any,
|
|
258
|
+
*,
|
|
259
|
+
run_id: uuid.UUID | None = None,
|
|
260
|
+
parent_run_id: uuid.UUID | None = None,
|
|
261
|
+
**kwargs: Any,
|
|
262
|
+
) -> Any:
|
|
263
|
+
"""Scan LLM response for threats.
|
|
264
|
+
|
|
265
|
+
Scans the generated response for potential data exfiltration,
|
|
266
|
+
harmful content, or policy violations.
|
|
267
|
+
"""
|
|
268
|
+
# Extract text from LLM response
|
|
269
|
+
text = self._extract_llm_response_text(response)
|
|
270
|
+
if not text:
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
result = self._scanner.scan(text, scan_type=ScanType.RESPONSE)
|
|
274
|
+
|
|
275
|
+
if result.has_threats:
|
|
276
|
+
self._handle_threat(result, "response", text[:100])
|
|
277
|
+
|
|
278
|
+
if self.block_on_response_threats:
|
|
279
|
+
raise SecurityException(result.pipeline_result)
|
|
280
|
+
|
|
281
|
+
def on_llm_error(
|
|
282
|
+
self,
|
|
283
|
+
error: BaseException,
|
|
284
|
+
*,
|
|
285
|
+
run_id: uuid.UUID | None = None,
|
|
286
|
+
parent_run_id: uuid.UUID | None = None,
|
|
287
|
+
**kwargs: Any,
|
|
288
|
+
) -> Any:
|
|
289
|
+
"""Handle LLM errors."""
|
|
290
|
+
logger.debug(
|
|
291
|
+
"LLM error occurred",
|
|
292
|
+
extra={"error": str(error), "trace_id": self.trace_id},
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# ========================================================================
|
|
296
|
+
# Chat Model Callbacks
|
|
297
|
+
# ========================================================================
|
|
298
|
+
|
|
299
|
+
def on_chat_model_start(
|
|
300
|
+
self,
|
|
301
|
+
serialized: dict[str, Any],
|
|
302
|
+
messages: list[list[Any]],
|
|
303
|
+
*,
|
|
304
|
+
run_id: uuid.UUID | None = None,
|
|
305
|
+
parent_run_id: uuid.UUID | None = None,
|
|
306
|
+
tags: list[str] | None = None,
|
|
307
|
+
metadata: dict[str, Any] | None = None,
|
|
308
|
+
**kwargs: Any,
|
|
309
|
+
) -> Any:
|
|
310
|
+
"""Scan chat messages before sending to model.
|
|
311
|
+
|
|
312
|
+
Handles ChatModel message format (list of messages).
|
|
313
|
+
"""
|
|
314
|
+
for message_batch in messages:
|
|
315
|
+
for message in message_batch:
|
|
316
|
+
text = self._extract_message_text(message)
|
|
317
|
+
if text:
|
|
318
|
+
result = self._scanner.scan(text, scan_type=ScanType.PROMPT)
|
|
319
|
+
|
|
320
|
+
if result.has_threats:
|
|
321
|
+
self._handle_threat(result, "chat_message", text[:100])
|
|
322
|
+
|
|
323
|
+
if self.block_on_prompt_threats:
|
|
324
|
+
raise SecurityException(result.pipeline_result)
|
|
325
|
+
|
|
326
|
+
# ========================================================================
|
|
327
|
+
# Tool Callbacks
|
|
328
|
+
# ========================================================================
|
|
329
|
+
|
|
330
|
+
def on_tool_start(
|
|
331
|
+
self,
|
|
332
|
+
serialized: dict[str, Any],
|
|
333
|
+
input_str: str,
|
|
334
|
+
*,
|
|
335
|
+
run_id: uuid.UUID | None = None,
|
|
336
|
+
parent_run_id: uuid.UUID | None = None,
|
|
337
|
+
tags: list[str] | None = None,
|
|
338
|
+
metadata: dict[str, Any] | None = None,
|
|
339
|
+
inputs: dict[str, Any] | None = None,
|
|
340
|
+
**kwargs: Any,
|
|
341
|
+
) -> Any:
|
|
342
|
+
"""Scan tool input before execution.
|
|
343
|
+
|
|
344
|
+
Validates tool calls against policy and scans inputs.
|
|
345
|
+
"""
|
|
346
|
+
if not self.scan_tools:
|
|
347
|
+
return
|
|
348
|
+
|
|
349
|
+
tool_name = serialized.get("name", "unknown")
|
|
350
|
+
|
|
351
|
+
# Scan tool input
|
|
352
|
+
result = self._scanner.scan_tool_call(
|
|
353
|
+
tool_name=tool_name,
|
|
354
|
+
tool_input=input_str,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
if result.has_threats:
|
|
358
|
+
self._handle_threat(result, f"tool:{tool_name}", input_str[:100])
|
|
359
|
+
|
|
360
|
+
if self.block_on_prompt_threats:
|
|
361
|
+
raise SecurityException(result.pipeline_result)
|
|
362
|
+
|
|
363
|
+
def on_tool_end(
|
|
364
|
+
self,
|
|
365
|
+
output: Any,
|
|
366
|
+
*,
|
|
367
|
+
run_id: uuid.UUID | None = None,
|
|
368
|
+
parent_run_id: uuid.UUID | None = None,
|
|
369
|
+
**kwargs: Any,
|
|
370
|
+
) -> Any:
|
|
371
|
+
"""Scan tool output."""
|
|
372
|
+
if not self.scan_tools:
|
|
373
|
+
return
|
|
374
|
+
|
|
375
|
+
text = str(output) if output else ""
|
|
376
|
+
if not text:
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
result = self._scanner.scan(text, scan_type=ScanType.TOOL_RESULT)
|
|
380
|
+
|
|
381
|
+
if result.has_threats:
|
|
382
|
+
self._handle_threat(result, "tool_output", text[:100])
|
|
383
|
+
|
|
384
|
+
def on_tool_error(
|
|
385
|
+
self,
|
|
386
|
+
error: BaseException,
|
|
387
|
+
*,
|
|
388
|
+
run_id: uuid.UUID | None = None,
|
|
389
|
+
parent_run_id: uuid.UUID | None = None,
|
|
390
|
+
**kwargs: Any,
|
|
391
|
+
) -> Any:
|
|
392
|
+
"""Handle tool errors."""
|
|
393
|
+
logger.debug(
|
|
394
|
+
"Tool error occurred",
|
|
395
|
+
extra={"error": str(error), "trace_id": self.trace_id},
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
# ========================================================================
|
|
399
|
+
# Agent Callbacks
|
|
400
|
+
# ========================================================================
|
|
401
|
+
|
|
402
|
+
def on_agent_action(
|
|
403
|
+
self,
|
|
404
|
+
action: Any,
|
|
405
|
+
*,
|
|
406
|
+
run_id: uuid.UUID | None = None,
|
|
407
|
+
parent_run_id: uuid.UUID | None = None,
|
|
408
|
+
**kwargs: Any,
|
|
409
|
+
) -> Any:
|
|
410
|
+
"""Scan agent action before execution."""
|
|
411
|
+
if not self.scan_agent_actions:
|
|
412
|
+
return
|
|
413
|
+
|
|
414
|
+
# Extract action details
|
|
415
|
+
tool_name = getattr(action, "tool", "unknown")
|
|
416
|
+
tool_input = getattr(action, "tool_input", "")
|
|
417
|
+
|
|
418
|
+
if isinstance(tool_input, dict):
|
|
419
|
+
tool_input = str(tool_input)
|
|
420
|
+
|
|
421
|
+
result = self._scanner.scan_tool_call(
|
|
422
|
+
tool_name=tool_name,
|
|
423
|
+
tool_input=tool_input,
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
if result.has_threats:
|
|
427
|
+
self._handle_threat(result, f"agent_action:{tool_name}", tool_input[:100])
|
|
428
|
+
|
|
429
|
+
if self.block_on_prompt_threats:
|
|
430
|
+
raise SecurityException(result.pipeline_result)
|
|
431
|
+
|
|
432
|
+
def on_agent_finish(
|
|
433
|
+
self,
|
|
434
|
+
finish: Any,
|
|
435
|
+
*,
|
|
436
|
+
run_id: uuid.UUID | None = None,
|
|
437
|
+
parent_run_id: uuid.UUID | None = None,
|
|
438
|
+
**kwargs: Any,
|
|
439
|
+
) -> Any:
|
|
440
|
+
"""Scan agent final output."""
|
|
441
|
+
output = getattr(finish, "return_values", {})
|
|
442
|
+
text = output.get("output", "") if isinstance(output, dict) else str(output)
|
|
443
|
+
|
|
444
|
+
if text:
|
|
445
|
+
result = self._scanner.scan(text, scan_type=ScanType.RESPONSE)
|
|
446
|
+
|
|
447
|
+
if result.has_threats:
|
|
448
|
+
self._handle_threat(result, "agent_finish", text[:100])
|
|
449
|
+
|
|
450
|
+
# ========================================================================
|
|
451
|
+
# Chain Callbacks
|
|
452
|
+
# ========================================================================
|
|
453
|
+
|
|
454
|
+
def on_chain_start(
|
|
455
|
+
self,
|
|
456
|
+
serialized: dict[str, Any],
|
|
457
|
+
inputs: dict[str, Any],
|
|
458
|
+
*,
|
|
459
|
+
run_id: uuid.UUID | None = None,
|
|
460
|
+
parent_run_id: uuid.UUID | None = None,
|
|
461
|
+
tags: list[str] | None = None,
|
|
462
|
+
metadata: dict[str, Any] | None = None,
|
|
463
|
+
**kwargs: Any,
|
|
464
|
+
) -> Any:
|
|
465
|
+
"""Track chain start for correlation."""
|
|
466
|
+
# Set trace ID for correlation
|
|
467
|
+
self.trace_id = str(run_id) if run_id else str(uuid.uuid4())
|
|
468
|
+
|
|
469
|
+
logger.debug(
|
|
470
|
+
"Chain started",
|
|
471
|
+
extra={
|
|
472
|
+
"chain_type": serialized.get("_type", "unknown"),
|
|
473
|
+
"trace_id": self.trace_id,
|
|
474
|
+
},
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
def on_chain_end(
|
|
478
|
+
self,
|
|
479
|
+
outputs: dict[str, Any],
|
|
480
|
+
*,
|
|
481
|
+
run_id: uuid.UUID | None = None,
|
|
482
|
+
parent_run_id: uuid.UUID | None = None,
|
|
483
|
+
**kwargs: Any,
|
|
484
|
+
) -> Any:
|
|
485
|
+
"""Track chain completion."""
|
|
486
|
+
logger.debug(
|
|
487
|
+
"Chain completed",
|
|
488
|
+
extra={"trace_id": self.trace_id},
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
def on_chain_error(
|
|
492
|
+
self,
|
|
493
|
+
error: BaseException,
|
|
494
|
+
*,
|
|
495
|
+
run_id: uuid.UUID | None = None,
|
|
496
|
+
parent_run_id: uuid.UUID | None = None,
|
|
497
|
+
**kwargs: Any,
|
|
498
|
+
) -> Any:
|
|
499
|
+
"""Handle chain errors."""
|
|
500
|
+
logger.debug(
|
|
501
|
+
"Chain error occurred",
|
|
502
|
+
extra={"error": str(error), "trace_id": self.trace_id},
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
# ========================================================================
|
|
506
|
+
# Retriever Callbacks (RAG)
|
|
507
|
+
# ========================================================================
|
|
508
|
+
|
|
509
|
+
def on_retriever_start(
|
|
510
|
+
self,
|
|
511
|
+
serialized: dict[str, Any],
|
|
512
|
+
query: str,
|
|
513
|
+
*,
|
|
514
|
+
run_id: uuid.UUID | None = None,
|
|
515
|
+
parent_run_id: uuid.UUID | None = None,
|
|
516
|
+
tags: list[str] | None = None,
|
|
517
|
+
metadata: dict[str, Any] | None = None,
|
|
518
|
+
**kwargs: Any,
|
|
519
|
+
) -> Any:
|
|
520
|
+
"""Scan retriever query."""
|
|
521
|
+
result = self._scanner.scan(query, scan_type=ScanType.PROMPT)
|
|
522
|
+
|
|
523
|
+
if result.has_threats:
|
|
524
|
+
self._handle_threat(result, "retriever_query", query[:100])
|
|
525
|
+
|
|
526
|
+
if self.block_on_prompt_threats:
|
|
527
|
+
raise SecurityException(result.pipeline_result)
|
|
528
|
+
|
|
529
|
+
def on_retriever_end(
|
|
530
|
+
self,
|
|
531
|
+
documents: list[Any],
|
|
532
|
+
*,
|
|
533
|
+
run_id: uuid.UUID | None = None,
|
|
534
|
+
parent_run_id: uuid.UUID | None = None,
|
|
535
|
+
**kwargs: Any,
|
|
536
|
+
) -> Any:
|
|
537
|
+
"""Optionally scan retrieved documents."""
|
|
538
|
+
# Future: Scan retrieved documents for RAG poisoning
|
|
539
|
+
pass
|
|
540
|
+
|
|
541
|
+
def on_retriever_error(
|
|
542
|
+
self,
|
|
543
|
+
error: BaseException,
|
|
544
|
+
*,
|
|
545
|
+
run_id: uuid.UUID | None = None,
|
|
546
|
+
parent_run_id: uuid.UUID | None = None,
|
|
547
|
+
**kwargs: Any,
|
|
548
|
+
) -> Any:
|
|
549
|
+
"""Handle retriever errors."""
|
|
550
|
+
logger.debug(
|
|
551
|
+
"Retriever error occurred",
|
|
552
|
+
extra={"error": str(error), "trace_id": self.trace_id},
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
# ========================================================================
|
|
556
|
+
# Text Callbacks
|
|
557
|
+
# ========================================================================
|
|
558
|
+
|
|
559
|
+
def on_text(
|
|
560
|
+
self,
|
|
561
|
+
text: str,
|
|
562
|
+
*,
|
|
563
|
+
run_id: uuid.UUID | None = None,
|
|
564
|
+
parent_run_id: uuid.UUID | None = None,
|
|
565
|
+
**kwargs: Any,
|
|
566
|
+
) -> Any:
|
|
567
|
+
"""Handle arbitrary text events."""
|
|
568
|
+
pass # Usually just logging, not security relevant
|
|
569
|
+
|
|
570
|
+
# ========================================================================
|
|
571
|
+
# Helper Methods
|
|
572
|
+
# ========================================================================
|
|
573
|
+
|
|
574
|
+
def _handle_threat(
|
|
575
|
+
self,
|
|
576
|
+
result: AgentScanResult,
|
|
577
|
+
context: str,
|
|
578
|
+
text_preview: str,
|
|
579
|
+
) -> None:
|
|
580
|
+
"""Handle detected threat.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
result: Scan result with threat details
|
|
584
|
+
context: Context description (e.g., "prompt", "response")
|
|
585
|
+
text_preview: Preview of scanned text for logging
|
|
586
|
+
"""
|
|
587
|
+
logger.warning(
|
|
588
|
+
"Security threat detected",
|
|
589
|
+
extra={
|
|
590
|
+
"context": context,
|
|
591
|
+
"severity": str(result.severity),
|
|
592
|
+
"detection_count": result.detection_count,
|
|
593
|
+
"trace_id": self.trace_id,
|
|
594
|
+
# Don't log actual text content for privacy
|
|
595
|
+
},
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
# Call user-provided callback if set
|
|
599
|
+
if self.on_threat:
|
|
600
|
+
try:
|
|
601
|
+
self.on_threat(result, context)
|
|
602
|
+
except Exception as e:
|
|
603
|
+
logger.error(f"Error in on_threat callback: {e}")
|
|
604
|
+
|
|
605
|
+
def _extract_llm_response_text(self, response: Any) -> str | None:
|
|
606
|
+
"""Extract text from LLM response object.
|
|
607
|
+
|
|
608
|
+
Uses unified extractor from raxe.sdk.integrations.extractors.
|
|
609
|
+
"""
|
|
610
|
+
return extract_text_from_response(response)
|
|
611
|
+
|
|
612
|
+
def _extract_message_text(self, message: Any) -> str | None:
|
|
613
|
+
"""Extract text from a chat message.
|
|
614
|
+
|
|
615
|
+
Uses unified extractor from raxe.sdk.integrations.extractors.
|
|
616
|
+
"""
|
|
617
|
+
return extract_text_from_message(message)
|
|
618
|
+
|
|
619
|
+
# ========================================================================
|
|
620
|
+
# Async Callback Methods
|
|
621
|
+
# ========================================================================
|
|
622
|
+
# LangChain supports async callbacks. These methods use the scanner's
|
|
623
|
+
# async methods for non-blocking operation in async contexts.
|
|
624
|
+
|
|
625
|
+
async def aon_llm_start(
|
|
626
|
+
self,
|
|
627
|
+
serialized: dict[str, Any],
|
|
628
|
+
prompts: list[str],
|
|
629
|
+
*,
|
|
630
|
+
run_id: uuid.UUID | None = None,
|
|
631
|
+
parent_run_id: uuid.UUID | None = None,
|
|
632
|
+
tags: list[str] | None = None,
|
|
633
|
+
metadata: dict[str, Any] | None = None,
|
|
634
|
+
**kwargs: Any,
|
|
635
|
+
) -> Any:
|
|
636
|
+
"""Async version of on_llm_start - scan prompts before LLM."""
|
|
637
|
+
import asyncio
|
|
638
|
+
|
|
639
|
+
for prompt in prompts:
|
|
640
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
641
|
+
None, lambda p=prompt: self._scanner.scan(p, scan_type=ScanType.PROMPT)
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
if result.has_threats:
|
|
645
|
+
self._handle_threat(result, "prompt", prompt[:100])
|
|
646
|
+
|
|
647
|
+
if self.block_on_prompt_threats:
|
|
648
|
+
raise SecurityException(result.pipeline_result)
|
|
649
|
+
|
|
650
|
+
async def aon_llm_end(
|
|
651
|
+
self,
|
|
652
|
+
response: Any,
|
|
653
|
+
*,
|
|
654
|
+
run_id: uuid.UUID | None = None,
|
|
655
|
+
parent_run_id: uuid.UUID | None = None,
|
|
656
|
+
**kwargs: Any,
|
|
657
|
+
) -> Any:
|
|
658
|
+
"""Async version of on_llm_end - scan LLM response."""
|
|
659
|
+
import asyncio
|
|
660
|
+
|
|
661
|
+
text = self._extract_llm_response_text(response)
|
|
662
|
+
if not text:
|
|
663
|
+
return
|
|
664
|
+
|
|
665
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
666
|
+
None, lambda: self._scanner.scan(text, scan_type=ScanType.RESPONSE)
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
if result.has_threats:
|
|
670
|
+
self._handle_threat(result, "response", text[:100])
|
|
671
|
+
|
|
672
|
+
if self.block_on_response_threats:
|
|
673
|
+
raise SecurityException(result.pipeline_result)
|
|
674
|
+
|
|
675
|
+
async def aon_chat_model_start(
|
|
676
|
+
self,
|
|
677
|
+
serialized: dict[str, Any],
|
|
678
|
+
messages: list[list[Any]],
|
|
679
|
+
*,
|
|
680
|
+
run_id: uuid.UUID | None = None,
|
|
681
|
+
parent_run_id: uuid.UUID | None = None,
|
|
682
|
+
tags: list[str] | None = None,
|
|
683
|
+
metadata: dict[str, Any] | None = None,
|
|
684
|
+
**kwargs: Any,
|
|
685
|
+
) -> Any:
|
|
686
|
+
"""Async version of on_chat_model_start - scan chat messages."""
|
|
687
|
+
import asyncio
|
|
688
|
+
|
|
689
|
+
for message_batch in messages:
|
|
690
|
+
for message in message_batch:
|
|
691
|
+
text = self._extract_message_text(message)
|
|
692
|
+
if text:
|
|
693
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
694
|
+
None, lambda t=text: self._scanner.scan(t, scan_type=ScanType.PROMPT)
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
if result.has_threats:
|
|
698
|
+
self._handle_threat(result, "chat_message", text[:100])
|
|
699
|
+
|
|
700
|
+
if self.block_on_prompt_threats:
|
|
701
|
+
raise SecurityException(result.pipeline_result)
|
|
702
|
+
|
|
703
|
+
async def aon_tool_start(
|
|
704
|
+
self,
|
|
705
|
+
serialized: dict[str, Any],
|
|
706
|
+
input_str: str,
|
|
707
|
+
*,
|
|
708
|
+
run_id: uuid.UUID | None = None,
|
|
709
|
+
parent_run_id: uuid.UUID | None = None,
|
|
710
|
+
tags: list[str] | None = None,
|
|
711
|
+
metadata: dict[str, Any] | None = None,
|
|
712
|
+
inputs: dict[str, Any] | None = None,
|
|
713
|
+
**kwargs: Any,
|
|
714
|
+
) -> Any:
|
|
715
|
+
"""Async version of on_tool_start - scan tool input."""
|
|
716
|
+
import asyncio
|
|
717
|
+
|
|
718
|
+
if not self.scan_tools:
|
|
719
|
+
return
|
|
720
|
+
|
|
721
|
+
tool_name = serialized.get("name", "unknown")
|
|
722
|
+
|
|
723
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
724
|
+
None,
|
|
725
|
+
lambda: self._scanner.scan_tool_call(
|
|
726
|
+
tool_name=tool_name, tool_input=input_str
|
|
727
|
+
),
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
if result.has_threats:
|
|
731
|
+
self._handle_threat(result, f"tool:{tool_name}", input_str[:100])
|
|
732
|
+
|
|
733
|
+
if self.block_on_prompt_threats:
|
|
734
|
+
raise SecurityException(result.pipeline_result)
|
|
735
|
+
|
|
736
|
+
async def aon_tool_end(
|
|
737
|
+
self,
|
|
738
|
+
output: Any,
|
|
739
|
+
*,
|
|
740
|
+
run_id: uuid.UUID | None = None,
|
|
741
|
+
parent_run_id: uuid.UUID | None = None,
|
|
742
|
+
**kwargs: Any,
|
|
743
|
+
) -> Any:
|
|
744
|
+
"""Async version of on_tool_end - scan tool output."""
|
|
745
|
+
import asyncio
|
|
746
|
+
|
|
747
|
+
if not self.scan_tools:
|
|
748
|
+
return
|
|
749
|
+
|
|
750
|
+
text = str(output) if output else ""
|
|
751
|
+
if not text:
|
|
752
|
+
return
|
|
753
|
+
|
|
754
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
755
|
+
None, lambda: self._scanner.scan(text, scan_type=ScanType.TOOL_RESULT)
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
if result.has_threats:
|
|
759
|
+
self._handle_threat(result, "tool_output", text[:100])
|
|
760
|
+
|
|
761
|
+
async def aon_chain_start(
|
|
762
|
+
self,
|
|
763
|
+
serialized: dict[str, Any],
|
|
764
|
+
inputs: dict[str, Any],
|
|
765
|
+
*,
|
|
766
|
+
run_id: uuid.UUID | None = None,
|
|
767
|
+
parent_run_id: uuid.UUID | None = None,
|
|
768
|
+
tags: list[str] | None = None,
|
|
769
|
+
metadata: dict[str, Any] | None = None,
|
|
770
|
+
**kwargs: Any,
|
|
771
|
+
) -> Any:
|
|
772
|
+
"""Async version of on_chain_start - track chain start."""
|
|
773
|
+
self.trace_id = str(run_id) if run_id else str(uuid.uuid4())
|
|
774
|
+
|
|
775
|
+
logger.debug(
|
|
776
|
+
"Chain started (async)",
|
|
777
|
+
extra={
|
|
778
|
+
"chain_type": serialized.get("_type", "unknown"),
|
|
779
|
+
"trace_id": self.trace_id,
|
|
780
|
+
},
|
|
781
|
+
)
|
|
782
|
+
|
|
783
|
+
async def aon_chain_end(
|
|
784
|
+
self,
|
|
785
|
+
outputs: dict[str, Any],
|
|
786
|
+
*,
|
|
787
|
+
run_id: uuid.UUID | None = None,
|
|
788
|
+
parent_run_id: uuid.UUID | None = None,
|
|
789
|
+
**kwargs: Any,
|
|
790
|
+
) -> Any:
|
|
791
|
+
"""Async version of on_chain_end - track chain completion."""
|
|
792
|
+
logger.debug(
|
|
793
|
+
"Chain completed (async)",
|
|
794
|
+
extra={"trace_id": self.trace_id},
|
|
795
|
+
)
|
|
796
|
+
|
|
797
|
+
async def aon_retriever_start(
|
|
798
|
+
self,
|
|
799
|
+
serialized: dict[str, Any],
|
|
800
|
+
query: str,
|
|
801
|
+
*,
|
|
802
|
+
run_id: uuid.UUID | None = None,
|
|
803
|
+
parent_run_id: uuid.UUID | None = None,
|
|
804
|
+
tags: list[str] | None = None,
|
|
805
|
+
metadata: dict[str, Any] | None = None,
|
|
806
|
+
**kwargs: Any,
|
|
807
|
+
) -> Any:
|
|
808
|
+
"""Async version of on_retriever_start - scan retriever query."""
|
|
809
|
+
import asyncio
|
|
810
|
+
|
|
811
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
812
|
+
None, lambda: self._scanner.scan(query, scan_type=ScanType.PROMPT)
|
|
813
|
+
)
|
|
814
|
+
|
|
815
|
+
if result.has_threats:
|
|
816
|
+
self._handle_threat(result, "retriever_query", query[:100])
|
|
817
|
+
|
|
818
|
+
if self.block_on_prompt_threats:
|
|
819
|
+
raise SecurityException(result.pipeline_result)
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
# ============================================================================
|
|
823
|
+
# Factory Function for RaxeCallbackHandler
|
|
824
|
+
# ============================================================================
|
|
825
|
+
|
|
826
|
+
_RaxeCallbackHandlerClass: type | None = None
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
def _create_callback_handler_class() -> type:
|
|
830
|
+
"""Create RaxeCallbackHandler class with proper inheritance.
|
|
831
|
+
|
|
832
|
+
This is called on first instantiation to ensure LangChain is available.
|
|
833
|
+
"""
|
|
834
|
+
global _RaxeCallbackHandlerClass
|
|
835
|
+
|
|
836
|
+
if _RaxeCallbackHandlerClass is not None:
|
|
837
|
+
return _RaxeCallbackHandlerClass
|
|
838
|
+
|
|
839
|
+
base_class = _get_base_callback_handler_class()
|
|
840
|
+
|
|
841
|
+
# Create class dynamically with proper inheritance
|
|
842
|
+
# Put mixin FIRST to ensure its methods take precedence
|
|
843
|
+
if base_class is not object:
|
|
844
|
+
bases = (_RaxeCallbackHandlerMixin, base_class)
|
|
845
|
+
else:
|
|
846
|
+
bases = (_RaxeCallbackHandlerMixin,)
|
|
847
|
+
|
|
848
|
+
_RaxeCallbackHandlerClass = type(
|
|
849
|
+
"RaxeCallbackHandler",
|
|
850
|
+
bases,
|
|
851
|
+
{
|
|
852
|
+
"__doc__": _RaxeCallbackHandlerMixin.__doc__,
|
|
853
|
+
"__module__": __name__,
|
|
854
|
+
}
|
|
855
|
+
)
|
|
856
|
+
|
|
857
|
+
return _RaxeCallbackHandlerClass
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
class RaxeCallbackHandler:
|
|
861
|
+
"""LangChain callback handler for automatic RAXE scanning.
|
|
862
|
+
|
|
863
|
+
This class dynamically inherits from LangChain's BaseCallbackHandler
|
|
864
|
+
when instantiated, ensuring compatibility with LangChain's type checks.
|
|
865
|
+
"""
|
|
866
|
+
|
|
867
|
+
def __new__(cls, *args, **kwargs):
|
|
868
|
+
"""Create instance of dynamically-generated handler class."""
|
|
869
|
+
handler_class = _create_callback_handler_class()
|
|
870
|
+
instance = object.__new__(handler_class)
|
|
871
|
+
# Initialize the instance here since __init__ won't be called
|
|
872
|
+
# on the returned instance (it's a different class)
|
|
873
|
+
_RaxeCallbackHandlerMixin.__init__(instance, *args, **kwargs)
|
|
874
|
+
return instance
|
|
875
|
+
|
|
876
|
+
def __init__(
|
|
877
|
+
self,
|
|
878
|
+
raxe_client: Raxe | None = None,
|
|
879
|
+
*,
|
|
880
|
+
scanner: AgentScanner | None = None,
|
|
881
|
+
tool_policy: ToolPolicy | None = None,
|
|
882
|
+
block_on_prompt_threats: bool = False,
|
|
883
|
+
block_on_response_threats: bool = False,
|
|
884
|
+
scan_tools: bool = True,
|
|
885
|
+
scan_agent_actions: bool = True,
|
|
886
|
+
on_threat: Any | None = None,
|
|
887
|
+
) -> None:
|
|
888
|
+
# This __init__ is never called when __new__ returns a different class
|
|
889
|
+
# The initialization is done in __new__ above
|
|
890
|
+
pass
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
# ============================================================================
|
|
894
|
+
# Convenience Functions
|
|
895
|
+
# ============================================================================
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
def create_callback_handler(
|
|
899
|
+
raxe_client: Raxe | None = None,
|
|
900
|
+
*,
|
|
901
|
+
tool_policy: ToolPolicy | None = None,
|
|
902
|
+
block_on_prompt_threats: bool = False,
|
|
903
|
+
block_on_response_threats: bool = False,
|
|
904
|
+
**kwargs: Any,
|
|
905
|
+
) -> RaxeCallbackHandler:
|
|
906
|
+
"""Factory function to create RaxeCallbackHandler.
|
|
907
|
+
|
|
908
|
+
This is a convenience function that creates a RaxeCallbackHandler
|
|
909
|
+
with the specified configuration.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
raxe_client: Optional Raxe instance
|
|
913
|
+
tool_policy: Policy for tool validation
|
|
914
|
+
block_on_prompt_threats: Block on prompt threats
|
|
915
|
+
block_on_response_threats: Block on response threats
|
|
916
|
+
**kwargs: Additional arguments passed to handler
|
|
917
|
+
|
|
918
|
+
Returns:
|
|
919
|
+
Configured RaxeCallbackHandler instance
|
|
920
|
+
"""
|
|
921
|
+
return RaxeCallbackHandler(
|
|
922
|
+
raxe_client=raxe_client,
|
|
923
|
+
tool_policy=tool_policy,
|
|
924
|
+
block_on_prompt_threats=block_on_prompt_threats,
|
|
925
|
+
block_on_response_threats=block_on_response_threats,
|
|
926
|
+
**kwargs,
|
|
927
|
+
)
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
def get_langchain_version() -> tuple[int, int, int]:
|
|
931
|
+
"""Get the installed LangChain version.
|
|
932
|
+
|
|
933
|
+
Returns:
|
|
934
|
+
Tuple of (major, minor, patch) version numbers.
|
|
935
|
+
"""
|
|
936
|
+
return _detect_langchain_version()
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
# ============================================================================
|
|
940
|
+
# Exports
|
|
941
|
+
# ============================================================================
|
|
942
|
+
|
|
943
|
+
__all__ = [
|
|
944
|
+
"RaxeCallbackHandler",
|
|
945
|
+
"ToolPolicy",
|
|
946
|
+
"create_callback_handler",
|
|
947
|
+
"get_langchain_version",
|
|
948
|
+
]
|