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,1282 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Telemetry event factory module with all 12 event types.
|
|
3
|
+
|
|
4
|
+
This module contains ONLY pure functions - no I/O operations.
|
|
5
|
+
All functions take data and return data without side effects.
|
|
6
|
+
|
|
7
|
+
Event Types:
|
|
8
|
+
- installation: Fired once on first import/install
|
|
9
|
+
- activation: Tracks first use of specific features
|
|
10
|
+
- session_start: Fired when Python interpreter session begins
|
|
11
|
+
- session_end: Fired when session ends
|
|
12
|
+
- scan: Core telemetry event for each threat detection scan
|
|
13
|
+
- error: Fired when an error occurs
|
|
14
|
+
- performance: Aggregated performance metrics
|
|
15
|
+
- feature_usage: Tracks usage of specific features
|
|
16
|
+
- heartbeat: Periodic health signal
|
|
17
|
+
- key_upgrade: Fired when API key is upgraded
|
|
18
|
+
- config_changed: Fired when configuration is changed
|
|
19
|
+
- team_invite: Tracks team invitations for viral growth metrics
|
|
20
|
+
|
|
21
|
+
Priority Assignment:
|
|
22
|
+
- Critical: installation, activation, session_end, error, key_upgrade, team_invite
|
|
23
|
+
- Standard: session_start, performance, feature_usage, heartbeat
|
|
24
|
+
- Conditional: scan (critical if threat HIGH+), config_changed (critical if disabling telemetry)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from dataclasses import dataclass
|
|
28
|
+
from datetime import datetime, timezone
|
|
29
|
+
from enum import Enum
|
|
30
|
+
from typing import Any, Literal
|
|
31
|
+
from uuid import uuid4
|
|
32
|
+
|
|
33
|
+
from .event_creator import hash_text
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class EventType(str, Enum):
|
|
37
|
+
"""Enumeration of all telemetry event types."""
|
|
38
|
+
|
|
39
|
+
INSTALLATION = "installation"
|
|
40
|
+
ACTIVATION = "activation"
|
|
41
|
+
SESSION_START = "session_start"
|
|
42
|
+
SESSION_END = "session_end"
|
|
43
|
+
SCAN = "scan"
|
|
44
|
+
ERROR = "error"
|
|
45
|
+
PERFORMANCE = "performance"
|
|
46
|
+
FEATURE_USAGE = "feature_usage"
|
|
47
|
+
HEARTBEAT = "heartbeat"
|
|
48
|
+
KEY_UPGRADE = "key_upgrade"
|
|
49
|
+
CONFIG_CHANGED = "config_changed"
|
|
50
|
+
TEAM_INVITE = "team_invite"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class TelemetryEvent:
|
|
55
|
+
"""Immutable telemetry event container.
|
|
56
|
+
|
|
57
|
+
Attributes:
|
|
58
|
+
event_id: Unique event identifier with evt_ prefix.
|
|
59
|
+
event_type: Type of event from EventType enum.
|
|
60
|
+
timestamp: ISO 8601 UTC timestamp of event creation.
|
|
61
|
+
priority: Event priority level (critical or standard).
|
|
62
|
+
payload: Event-specific data dictionary.
|
|
63
|
+
org_id: Organization ID for multi-tenant tracking (optional).
|
|
64
|
+
team_id: Team ID for team-level analytics (optional).
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
event_id: str
|
|
68
|
+
event_type: str
|
|
69
|
+
timestamp: str
|
|
70
|
+
priority: Literal["critical", "standard"]
|
|
71
|
+
payload: dict[str, Any]
|
|
72
|
+
org_id: str | None = None
|
|
73
|
+
team_id: str | None = None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# =============================================================================
|
|
77
|
+
# ID Generators
|
|
78
|
+
# =============================================================================
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def generate_event_id() -> str:
|
|
82
|
+
"""Generate a unique event identifier.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Event ID with evt_ prefix followed by 16 hex characters.
|
|
86
|
+
|
|
87
|
+
Example:
|
|
88
|
+
>>> generate_event_id()
|
|
89
|
+
'evt_a1b2c3d4e5f67890'
|
|
90
|
+
"""
|
|
91
|
+
return f"evt_{uuid4().hex[:16]}"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def generate_installation_id() -> str:
|
|
95
|
+
"""Generate a unique installation identifier.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Installation ID with inst_ prefix followed by 16 hex characters.
|
|
99
|
+
|
|
100
|
+
Example:
|
|
101
|
+
>>> generate_installation_id()
|
|
102
|
+
'inst_a1b2c3d4e5f67890'
|
|
103
|
+
"""
|
|
104
|
+
return f"inst_{uuid4().hex[:16]}"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def generate_session_id() -> str:
|
|
108
|
+
"""Generate a unique session identifier.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Session ID with sess_ prefix followed by 16 hex characters.
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
>>> generate_session_id()
|
|
115
|
+
'sess_a1b2c3d4e5f67890'
|
|
116
|
+
"""
|
|
117
|
+
return f"sess_{uuid4().hex[:16]}"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def generate_batch_id() -> str:
|
|
121
|
+
"""Generate a unique batch identifier.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Batch ID with batch_ prefix followed by 16 hex characters.
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
>>> generate_batch_id()
|
|
128
|
+
'batch_a1b2c3d4e5f67890'
|
|
129
|
+
"""
|
|
130
|
+
return f"batch_{uuid4().hex[:16]}"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _get_utc_timestamp() -> str:
|
|
134
|
+
"""Get current UTC timestamp in ISO 8601 format.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
ISO 8601 formatted UTC timestamp string.
|
|
138
|
+
"""
|
|
139
|
+
return datetime.now(timezone.utc).isoformat()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# =============================================================================
|
|
143
|
+
# Installation Event
|
|
144
|
+
# =============================================================================
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def create_installation_event(
|
|
148
|
+
installation_id: str,
|
|
149
|
+
client_version: str,
|
|
150
|
+
python_version: str,
|
|
151
|
+
platform: Literal["darwin", "linux", "win32"],
|
|
152
|
+
install_method: Literal["pip", "uv", "pipx", "poetry", "conda", "source", "docker", "unknown"],
|
|
153
|
+
*,
|
|
154
|
+
key_type: Literal["temp", "community", "pro", "enterprise"] = "temp",
|
|
155
|
+
ml_available: bool | None = None,
|
|
156
|
+
installed_extras: list[str] | None = None,
|
|
157
|
+
platform_version: str | None = None,
|
|
158
|
+
acquisition_source: Literal[
|
|
159
|
+
"pip_install",
|
|
160
|
+
"github_release",
|
|
161
|
+
"docker",
|
|
162
|
+
"homebrew",
|
|
163
|
+
"website_download",
|
|
164
|
+
"referral",
|
|
165
|
+
"enterprise_deploy",
|
|
166
|
+
"ci_integration",
|
|
167
|
+
"unknown",
|
|
168
|
+
] = "unknown",
|
|
169
|
+
org_id: str | None = None,
|
|
170
|
+
team_id: str | None = None,
|
|
171
|
+
) -> TelemetryEvent:
|
|
172
|
+
"""Create an installation telemetry event.
|
|
173
|
+
|
|
174
|
+
Fired once on first import/install of RAXE.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
installation_id: Unique installation identifier (inst_ prefix).
|
|
178
|
+
client_version: RAXE version installed.
|
|
179
|
+
python_version: Python interpreter version.
|
|
180
|
+
platform: Operating system platform.
|
|
181
|
+
install_method: Package manager used for installation.
|
|
182
|
+
key_type: API key tier at installation time.
|
|
183
|
+
- temp: Temporary key (auto-generated, 14-day expiry)
|
|
184
|
+
- community: Free registered user
|
|
185
|
+
- pro: Paid individual user
|
|
186
|
+
- enterprise: Team/organization plan
|
|
187
|
+
ml_available: Whether ML dependencies are installed.
|
|
188
|
+
installed_extras: List of installed optional extras.
|
|
189
|
+
platform_version: OS version string.
|
|
190
|
+
acquisition_source: How the user discovered/acquired RAXE.
|
|
191
|
+
- pip_install: Installed via pip install raxe
|
|
192
|
+
- github_release: Downloaded from GitHub releases
|
|
193
|
+
- docker: Installed via Docker image
|
|
194
|
+
- homebrew: Installed via brew install raxe
|
|
195
|
+
- website_download: Downloaded from raxe.ai
|
|
196
|
+
- referral: Referred by another user (via RAXE_REFERRAL_CODE)
|
|
197
|
+
- enterprise_deploy: Enterprise deployment
|
|
198
|
+
- ci_integration: Installed in CI/CD pipeline
|
|
199
|
+
- unknown: Default/fallback
|
|
200
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
201
|
+
team_id: Team ID for team-level analytics.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
TelemetryEvent with installation payload.
|
|
205
|
+
|
|
206
|
+
Example:
|
|
207
|
+
>>> event = create_installation_event(
|
|
208
|
+
... installation_id="inst_abc123",
|
|
209
|
+
... client_version="0.0.1",
|
|
210
|
+
... python_version="3.11.5",
|
|
211
|
+
... platform="darwin",
|
|
212
|
+
... install_method="pip",
|
|
213
|
+
... ml_available=True,
|
|
214
|
+
... installed_extras=["ml", "openai"],
|
|
215
|
+
... acquisition_source="pip_install",
|
|
216
|
+
... org_id="org_123",
|
|
217
|
+
... team_id="team_456",
|
|
218
|
+
... )
|
|
219
|
+
"""
|
|
220
|
+
payload: dict[str, Any] = {
|
|
221
|
+
"installation_id": installation_id,
|
|
222
|
+
"client_version": client_version,
|
|
223
|
+
"python_version": python_version,
|
|
224
|
+
"platform": platform,
|
|
225
|
+
"install_method": install_method,
|
|
226
|
+
"key_type": key_type,
|
|
227
|
+
"acquisition_source": acquisition_source,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if ml_available is not None:
|
|
231
|
+
payload["ml_available"] = ml_available
|
|
232
|
+
|
|
233
|
+
if installed_extras is not None:
|
|
234
|
+
payload["installed_extras"] = installed_extras
|
|
235
|
+
|
|
236
|
+
if platform_version is not None:
|
|
237
|
+
payload["platform_version"] = platform_version
|
|
238
|
+
|
|
239
|
+
return TelemetryEvent(
|
|
240
|
+
event_id=generate_event_id(),
|
|
241
|
+
event_type=EventType.INSTALLATION.value,
|
|
242
|
+
timestamp=_get_utc_timestamp(),
|
|
243
|
+
priority="critical",
|
|
244
|
+
payload=payload,
|
|
245
|
+
org_id=org_id,
|
|
246
|
+
team_id=team_id,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
# =============================================================================
|
|
251
|
+
# Activation Event
|
|
252
|
+
# =============================================================================
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def create_activation_event(
|
|
256
|
+
feature: Literal[
|
|
257
|
+
"first_scan",
|
|
258
|
+
"first_threat",
|
|
259
|
+
"first_block",
|
|
260
|
+
"first_cli",
|
|
261
|
+
"first_sdk",
|
|
262
|
+
"first_decorator",
|
|
263
|
+
"first_wrapper",
|
|
264
|
+
"first_langchain",
|
|
265
|
+
"first_l2_detection",
|
|
266
|
+
"first_custom_rule",
|
|
267
|
+
],
|
|
268
|
+
seconds_since_install: float,
|
|
269
|
+
*,
|
|
270
|
+
activation_context: dict[str, Any] | None = None,
|
|
271
|
+
org_id: str | None = None,
|
|
272
|
+
team_id: str | None = None,
|
|
273
|
+
) -> TelemetryEvent:
|
|
274
|
+
"""Create an activation telemetry event.
|
|
275
|
+
|
|
276
|
+
Tracks first use of specific features (time-to-value metrics).
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
feature: Feature being activated for the first time.
|
|
280
|
+
Canonical values aligned with backend:
|
|
281
|
+
- first_scan: First prompt scan performed
|
|
282
|
+
- first_threat: First threat detected
|
|
283
|
+
- first_block: First threat blocked by policy
|
|
284
|
+
- first_cli: First CLI command executed
|
|
285
|
+
- first_sdk: First SDK API call
|
|
286
|
+
- first_decorator: First use of @protect decorator
|
|
287
|
+
- first_wrapper: First use of OpenAI/Anthropic wrapper
|
|
288
|
+
- first_langchain: First LangChain integration use
|
|
289
|
+
- first_l2_detection: First ML-based (L2) detection
|
|
290
|
+
- first_custom_rule: First custom rule loaded
|
|
291
|
+
seconds_since_install: Time elapsed since installation event.
|
|
292
|
+
activation_context: Additional context about the activation.
|
|
293
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
294
|
+
team_id: Team ID for team-level analytics.
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
TelemetryEvent with activation payload.
|
|
298
|
+
|
|
299
|
+
Example:
|
|
300
|
+
>>> event = create_activation_event(
|
|
301
|
+
... feature="first_scan",
|
|
302
|
+
... seconds_since_install=120.5,
|
|
303
|
+
... activation_context={"entry_point": "cli"},
|
|
304
|
+
... org_id="org_123",
|
|
305
|
+
... team_id="team_456",
|
|
306
|
+
... )
|
|
307
|
+
"""
|
|
308
|
+
payload: dict[str, Any] = {
|
|
309
|
+
"feature": feature,
|
|
310
|
+
"seconds_since_install": seconds_since_install,
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if activation_context is not None:
|
|
314
|
+
payload["activation_context"] = activation_context
|
|
315
|
+
|
|
316
|
+
return TelemetryEvent(
|
|
317
|
+
event_id=generate_event_id(),
|
|
318
|
+
event_type=EventType.ACTIVATION.value,
|
|
319
|
+
timestamp=_get_utc_timestamp(),
|
|
320
|
+
priority="critical",
|
|
321
|
+
payload=payload,
|
|
322
|
+
org_id=org_id,
|
|
323
|
+
team_id=team_id,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# =============================================================================
|
|
328
|
+
# Session Start Event
|
|
329
|
+
# =============================================================================
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def create_session_start_event(
|
|
333
|
+
session_id: str,
|
|
334
|
+
session_number: int,
|
|
335
|
+
*,
|
|
336
|
+
entry_point: Literal["cli", "sdk", "wrapper", "integration", "repl"] | None = None,
|
|
337
|
+
previous_session_gap_hours: float | None = None,
|
|
338
|
+
environment: dict[str, bool] | None = None,
|
|
339
|
+
org_id: str | None = None,
|
|
340
|
+
team_id: str | None = None,
|
|
341
|
+
) -> TelemetryEvent:
|
|
342
|
+
"""Create a session start telemetry event.
|
|
343
|
+
|
|
344
|
+
Fired when a new Python interpreter session begins (DAU/WAU/MAU tracking).
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
session_id: Unique session identifier (sess_ prefix).
|
|
348
|
+
session_number: Sequential session count for this installation.
|
|
349
|
+
entry_point: How RAXE was invoked.
|
|
350
|
+
previous_session_gap_hours: Hours since last session ended.
|
|
351
|
+
environment: Session environment details (is_ci, is_interactive, is_notebook).
|
|
352
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
353
|
+
team_id: Team ID for team-level analytics.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
TelemetryEvent with session_start payload.
|
|
357
|
+
|
|
358
|
+
Example:
|
|
359
|
+
>>> event = create_session_start_event(
|
|
360
|
+
... session_id="sess_abc123",
|
|
361
|
+
... session_number=5,
|
|
362
|
+
... entry_point="cli",
|
|
363
|
+
... previous_session_gap_hours=24.5,
|
|
364
|
+
... environment={"is_ci": False, "is_interactive": True},
|
|
365
|
+
... org_id="org_123",
|
|
366
|
+
... team_id="team_456",
|
|
367
|
+
... )
|
|
368
|
+
"""
|
|
369
|
+
payload: dict[str, Any] = {
|
|
370
|
+
"session_id": session_id,
|
|
371
|
+
"session_number": session_number,
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if entry_point is not None:
|
|
375
|
+
payload["entry_point"] = entry_point
|
|
376
|
+
|
|
377
|
+
if previous_session_gap_hours is not None:
|
|
378
|
+
payload["previous_session_gap_hours"] = previous_session_gap_hours
|
|
379
|
+
|
|
380
|
+
if environment is not None:
|
|
381
|
+
payload["environment"] = environment
|
|
382
|
+
|
|
383
|
+
return TelemetryEvent(
|
|
384
|
+
event_id=generate_event_id(),
|
|
385
|
+
event_type=EventType.SESSION_START.value,
|
|
386
|
+
timestamp=_get_utc_timestamp(),
|
|
387
|
+
priority="standard",
|
|
388
|
+
payload=payload,
|
|
389
|
+
org_id=org_id,
|
|
390
|
+
team_id=team_id,
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# =============================================================================
|
|
395
|
+
# Session End Event
|
|
396
|
+
# =============================================================================
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def create_session_end_event(
|
|
400
|
+
session_id: str,
|
|
401
|
+
duration_seconds: float,
|
|
402
|
+
scans_in_session: int,
|
|
403
|
+
threats_in_session: int,
|
|
404
|
+
*,
|
|
405
|
+
end_reason: Literal["normal", "error", "timeout", "interrupt", "unknown"] | None = None,
|
|
406
|
+
peak_memory_mb: float | None = None,
|
|
407
|
+
features_used: list[str] | None = None,
|
|
408
|
+
org_id: str | None = None,
|
|
409
|
+
team_id: str | None = None,
|
|
410
|
+
) -> TelemetryEvent:
|
|
411
|
+
"""Create a session end telemetry event.
|
|
412
|
+
|
|
413
|
+
Fired when Python interpreter session ends (engagement metrics).
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
session_id: Session being ended (sess_ prefix).
|
|
417
|
+
duration_seconds: Total session duration.
|
|
418
|
+
scans_in_session: Number of scans performed.
|
|
419
|
+
threats_in_session: Number of threats detected.
|
|
420
|
+
end_reason: How session ended.
|
|
421
|
+
peak_memory_mb: Peak memory usage during session.
|
|
422
|
+
features_used: Features used during session.
|
|
423
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
424
|
+
team_id: Team ID for team-level analytics.
|
|
425
|
+
|
|
426
|
+
Returns:
|
|
427
|
+
TelemetryEvent with session_end payload.
|
|
428
|
+
|
|
429
|
+
Example:
|
|
430
|
+
>>> event = create_session_end_event(
|
|
431
|
+
... session_id="sess_abc123",
|
|
432
|
+
... duration_seconds=3600.0,
|
|
433
|
+
... scans_in_session=50,
|
|
434
|
+
... threats_in_session=3,
|
|
435
|
+
... end_reason="normal",
|
|
436
|
+
... peak_memory_mb=150.5,
|
|
437
|
+
... features_used=["cli", "explain"],
|
|
438
|
+
... org_id="org_123",
|
|
439
|
+
... team_id="team_456",
|
|
440
|
+
... )
|
|
441
|
+
"""
|
|
442
|
+
payload: dict[str, Any] = {
|
|
443
|
+
"session_id": session_id,
|
|
444
|
+
"duration_seconds": duration_seconds,
|
|
445
|
+
"scans_in_session": scans_in_session,
|
|
446
|
+
"threats_in_session": threats_in_session,
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if end_reason is not None:
|
|
450
|
+
payload["end_reason"] = end_reason
|
|
451
|
+
|
|
452
|
+
if peak_memory_mb is not None:
|
|
453
|
+
payload["peak_memory_mb"] = peak_memory_mb
|
|
454
|
+
|
|
455
|
+
if features_used is not None:
|
|
456
|
+
payload["features_used"] = features_used
|
|
457
|
+
|
|
458
|
+
return TelemetryEvent(
|
|
459
|
+
event_id=generate_event_id(),
|
|
460
|
+
event_type=EventType.SESSION_END.value,
|
|
461
|
+
timestamp=_get_utc_timestamp(),
|
|
462
|
+
priority="critical",
|
|
463
|
+
payload=payload,
|
|
464
|
+
org_id=org_id,
|
|
465
|
+
team_id=team_id,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
# =============================================================================
|
|
470
|
+
# Scan Event
|
|
471
|
+
# =============================================================================
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def create_scan_event(
|
|
475
|
+
prompt_hash: str,
|
|
476
|
+
threat_detected: bool,
|
|
477
|
+
scan_duration_ms: float,
|
|
478
|
+
*,
|
|
479
|
+
event_id: str | None = None,
|
|
480
|
+
detection_count: int | None = None,
|
|
481
|
+
highest_severity: Literal["none", "low", "medium", "high", "critical"] | None = None,
|
|
482
|
+
rule_ids: list[str] | None = None,
|
|
483
|
+
families: list[str] | None = None,
|
|
484
|
+
l1_duration_ms: float | None = None,
|
|
485
|
+
l2_duration_ms: float | None = None,
|
|
486
|
+
l1_hit: bool | None = None,
|
|
487
|
+
l2_hit: bool | None = None,
|
|
488
|
+
l2_enabled: bool | None = None,
|
|
489
|
+
prompt_length: int | None = None,
|
|
490
|
+
action_taken: Literal["allow", "block", "warn", "redact"] | None = None,
|
|
491
|
+
entry_point: Literal["cli", "sdk", "wrapper", "integration"] | None = None,
|
|
492
|
+
wrapper_type: Literal["openai", "anthropic", "langchain", "none"] | None = None,
|
|
493
|
+
org_id: str | None = None,
|
|
494
|
+
team_id: str | None = None,
|
|
495
|
+
) -> TelemetryEvent:
|
|
496
|
+
"""Create a scan telemetry event.
|
|
497
|
+
|
|
498
|
+
Core telemetry event for each threat detection scan.
|
|
499
|
+
|
|
500
|
+
Args:
|
|
501
|
+
prompt_hash: SHA-256 hash of prompt for deduplication.
|
|
502
|
+
threat_detected: Whether any threat was detected.
|
|
503
|
+
scan_duration_ms: Total scan duration in milliseconds.
|
|
504
|
+
event_id: Optional event ID. If not provided, one will be generated.
|
|
505
|
+
detection_count: Number of detections found.
|
|
506
|
+
highest_severity: Highest severity among detections.
|
|
507
|
+
rule_ids: List of triggered rule IDs (up to 10).
|
|
508
|
+
families: Threat families detected (PI, JB, PII, etc.).
|
|
509
|
+
l1_duration_ms: L1 (rule-based) scan duration.
|
|
510
|
+
l2_duration_ms: L2 (ML-based) scan duration.
|
|
511
|
+
l1_hit: L1 detection triggered.
|
|
512
|
+
l2_hit: L2 detection triggered.
|
|
513
|
+
l2_enabled: Whether L2 was enabled for this scan.
|
|
514
|
+
prompt_length: Character length of scanned prompt.
|
|
515
|
+
action_taken: Action taken based on policy.
|
|
516
|
+
entry_point: How the scan was triggered.
|
|
517
|
+
wrapper_type: Wrapper used if applicable.
|
|
518
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
519
|
+
team_id: Team ID for team-level analytics.
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
TelemetryEvent with scan payload. Priority is critical if
|
|
523
|
+
highest_severity is HIGH or CRITICAL, otherwise standard.
|
|
524
|
+
|
|
525
|
+
Example:
|
|
526
|
+
>>> event = create_scan_event(
|
|
527
|
+
... prompt_hash="a" * 64,
|
|
528
|
+
... threat_detected=True,
|
|
529
|
+
... scan_duration_ms=4.5,
|
|
530
|
+
... detection_count=2,
|
|
531
|
+
... highest_severity="HIGH",
|
|
532
|
+
... rule_ids=["pi-001", "pi-002"],
|
|
533
|
+
... families=["PI"],
|
|
534
|
+
... org_id="org_123",
|
|
535
|
+
... team_id="team_456",
|
|
536
|
+
... )
|
|
537
|
+
"""
|
|
538
|
+
payload: dict[str, Any] = {
|
|
539
|
+
"prompt_hash": prompt_hash,
|
|
540
|
+
"threat_detected": threat_detected,
|
|
541
|
+
"scan_duration_ms": scan_duration_ms,
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if detection_count is not None:
|
|
545
|
+
payload["detection_count"] = detection_count
|
|
546
|
+
|
|
547
|
+
if highest_severity is not None:
|
|
548
|
+
payload["highest_severity"] = highest_severity
|
|
549
|
+
|
|
550
|
+
if rule_ids is not None:
|
|
551
|
+
# Limit to 10 rule IDs as per schema
|
|
552
|
+
payload["rule_ids"] = rule_ids[:10]
|
|
553
|
+
|
|
554
|
+
if families is not None:
|
|
555
|
+
payload["families"] = families
|
|
556
|
+
|
|
557
|
+
if l1_duration_ms is not None:
|
|
558
|
+
payload["l1_duration_ms"] = l1_duration_ms
|
|
559
|
+
|
|
560
|
+
if l2_duration_ms is not None:
|
|
561
|
+
payload["l2_duration_ms"] = l2_duration_ms
|
|
562
|
+
|
|
563
|
+
if l1_hit is not None:
|
|
564
|
+
payload["l1_hit"] = l1_hit
|
|
565
|
+
|
|
566
|
+
if l2_hit is not None:
|
|
567
|
+
payload["l2_hit"] = l2_hit
|
|
568
|
+
|
|
569
|
+
if l2_enabled is not None:
|
|
570
|
+
payload["l2_enabled"] = l2_enabled
|
|
571
|
+
|
|
572
|
+
if prompt_length is not None:
|
|
573
|
+
payload["prompt_length"] = prompt_length
|
|
574
|
+
|
|
575
|
+
if action_taken is not None:
|
|
576
|
+
payload["action_taken"] = action_taken
|
|
577
|
+
|
|
578
|
+
if entry_point is not None:
|
|
579
|
+
payload["entry_point"] = entry_point
|
|
580
|
+
|
|
581
|
+
if wrapper_type is not None:
|
|
582
|
+
payload["wrapper_type"] = wrapper_type
|
|
583
|
+
|
|
584
|
+
# Priority is critical if threat is HIGH or CRITICAL severity
|
|
585
|
+
priority: Literal["critical", "standard"] = "standard"
|
|
586
|
+
if highest_severity in ("high", "critical"):
|
|
587
|
+
priority = "critical"
|
|
588
|
+
|
|
589
|
+
return TelemetryEvent(
|
|
590
|
+
event_id=event_id if event_id else generate_event_id(),
|
|
591
|
+
event_type=EventType.SCAN.value,
|
|
592
|
+
timestamp=_get_utc_timestamp(),
|
|
593
|
+
priority=priority,
|
|
594
|
+
payload=payload,
|
|
595
|
+
org_id=org_id,
|
|
596
|
+
team_id=team_id,
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
# =============================================================================
|
|
601
|
+
# Scan Event v2.0 (Full L2 Telemetry)
|
|
602
|
+
# =============================================================================
|
|
603
|
+
|
|
604
|
+
# Schema version for v2 events
|
|
605
|
+
SCAN_SCHEMA_VERSION = "2.0.0"
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
def create_scan_event_v2(
|
|
609
|
+
payload: dict[str, Any],
|
|
610
|
+
*,
|
|
611
|
+
event_id: str | None = None,
|
|
612
|
+
org_id: str | None = None,
|
|
613
|
+
team_id: str | None = None,
|
|
614
|
+
) -> TelemetryEvent:
|
|
615
|
+
"""Create a scan telemetry event using schema v2.0.
|
|
616
|
+
|
|
617
|
+
This function accepts a pre-built payload from ScanTelemetryBuilder.
|
|
618
|
+
The payload must conform to SCAN_TELEMETRY_SCHEMA.md.
|
|
619
|
+
|
|
620
|
+
Args:
|
|
621
|
+
payload: Pre-built payload dict from ScanTelemetryBuilder.build()
|
|
622
|
+
event_id: Optional event ID. If not provided, one will be generated.
|
|
623
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
624
|
+
team_id: Team ID for team-level analytics.
|
|
625
|
+
|
|
626
|
+
Returns:
|
|
627
|
+
TelemetryEvent with scan payload and schema_version.
|
|
628
|
+
|
|
629
|
+
Example:
|
|
630
|
+
>>> from raxe.domain.telemetry.scan_telemetry_builder import build_scan_telemetry
|
|
631
|
+
>>> payload = build_scan_telemetry(prompt, l1_result, l2_result, duration_ms)
|
|
632
|
+
>>> event = create_scan_event_v2(payload)
|
|
633
|
+
"""
|
|
634
|
+
# Add schema version to payload
|
|
635
|
+
payload_with_version = {"schema_version": SCAN_SCHEMA_VERSION, **payload}
|
|
636
|
+
|
|
637
|
+
# Determine priority from L1/L2 severity
|
|
638
|
+
priority: Literal["critical", "standard"] = "standard"
|
|
639
|
+
|
|
640
|
+
# Check L1 severity
|
|
641
|
+
l1_block = payload.get("l1", {})
|
|
642
|
+
if l1_block.get("highest_severity") in ("high", "critical"):
|
|
643
|
+
priority = "critical"
|
|
644
|
+
|
|
645
|
+
# Check L2 classification
|
|
646
|
+
l2_block = payload.get("l2", {})
|
|
647
|
+
if l2_block.get("classification") in ("HIGH_THREAT", "THREAT"):
|
|
648
|
+
priority = "critical"
|
|
649
|
+
|
|
650
|
+
# Also critical if threat detected
|
|
651
|
+
if payload.get("threat_detected"):
|
|
652
|
+
priority = "critical"
|
|
653
|
+
|
|
654
|
+
return TelemetryEvent(
|
|
655
|
+
event_id=event_id if event_id else generate_event_id(),
|
|
656
|
+
event_type=EventType.SCAN.value,
|
|
657
|
+
timestamp=_get_utc_timestamp(),
|
|
658
|
+
priority=priority,
|
|
659
|
+
payload=payload_with_version,
|
|
660
|
+
org_id=org_id,
|
|
661
|
+
team_id=team_id,
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
# =============================================================================
|
|
666
|
+
# Error Event
|
|
667
|
+
# =============================================================================
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
def create_error_event(
|
|
671
|
+
error_type: Literal[
|
|
672
|
+
"validation_error",
|
|
673
|
+
"configuration_error",
|
|
674
|
+
"rule_loading_error",
|
|
675
|
+
"ml_model_error",
|
|
676
|
+
"network_error",
|
|
677
|
+
"permission_error",
|
|
678
|
+
"timeout_error",
|
|
679
|
+
"internal_error",
|
|
680
|
+
],
|
|
681
|
+
error_code: str,
|
|
682
|
+
component: Literal["cli", "sdk", "engine", "ml", "rules", "config", "telemetry", "wrapper"],
|
|
683
|
+
*,
|
|
684
|
+
error_message_hash: str | None = None,
|
|
685
|
+
operation: str | None = None,
|
|
686
|
+
is_recoverable: bool | None = None,
|
|
687
|
+
stack_trace_hash: str | None = None,
|
|
688
|
+
context: dict[str, str] | None = None,
|
|
689
|
+
org_id: str | None = None,
|
|
690
|
+
team_id: str | None = None,
|
|
691
|
+
) -> TelemetryEvent:
|
|
692
|
+
"""Create an error telemetry event.
|
|
693
|
+
|
|
694
|
+
Fired when an error occurs (for debugging and quality improvement).
|
|
695
|
+
|
|
696
|
+
Args:
|
|
697
|
+
error_type: Category of error.
|
|
698
|
+
error_code: Specific error code (e.g., RAXE_001).
|
|
699
|
+
component: Component where error occurred.
|
|
700
|
+
error_message_hash: SHA-256 hash of error message (for grouping without PII).
|
|
701
|
+
operation: Operation being performed when error occurred.
|
|
702
|
+
is_recoverable: Whether the error was recovered from.
|
|
703
|
+
stack_trace_hash: SHA-256 hash of stack trace (for grouping).
|
|
704
|
+
context: Non-sensitive error context (python_version, raxe_version, platform).
|
|
705
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
706
|
+
team_id: Team ID for team-level analytics.
|
|
707
|
+
|
|
708
|
+
Returns:
|
|
709
|
+
TelemetryEvent with error payload.
|
|
710
|
+
|
|
711
|
+
Example:
|
|
712
|
+
>>> event = create_error_event(
|
|
713
|
+
... error_type="validation_error",
|
|
714
|
+
... error_code="RAXE_001",
|
|
715
|
+
... component="engine",
|
|
716
|
+
... error_message_hash=hash_text("Invalid prompt format"),
|
|
717
|
+
... operation="scan",
|
|
718
|
+
... is_recoverable=True,
|
|
719
|
+
... org_id="org_123",
|
|
720
|
+
... team_id="team_456",
|
|
721
|
+
... )
|
|
722
|
+
"""
|
|
723
|
+
payload: dict[str, Any] = {
|
|
724
|
+
"error_type": error_type,
|
|
725
|
+
"error_code": error_code,
|
|
726
|
+
"component": component,
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if error_message_hash is not None:
|
|
730
|
+
payload["error_message_hash"] = error_message_hash
|
|
731
|
+
|
|
732
|
+
if operation is not None:
|
|
733
|
+
payload["operation"] = operation
|
|
734
|
+
|
|
735
|
+
if is_recoverable is not None:
|
|
736
|
+
payload["is_recoverable"] = is_recoverable
|
|
737
|
+
|
|
738
|
+
if stack_trace_hash is not None:
|
|
739
|
+
payload["stack_trace_hash"] = stack_trace_hash
|
|
740
|
+
|
|
741
|
+
if context is not None:
|
|
742
|
+
payload["context"] = context
|
|
743
|
+
|
|
744
|
+
return TelemetryEvent(
|
|
745
|
+
event_id=generate_event_id(),
|
|
746
|
+
event_type=EventType.ERROR.value,
|
|
747
|
+
timestamp=_get_utc_timestamp(),
|
|
748
|
+
priority="critical",
|
|
749
|
+
payload=payload,
|
|
750
|
+
org_id=org_id,
|
|
751
|
+
team_id=team_id,
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
# =============================================================================
|
|
756
|
+
# Performance Event
|
|
757
|
+
# =============================================================================
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
def create_performance_event(
|
|
761
|
+
period_start: str,
|
|
762
|
+
period_end: str,
|
|
763
|
+
scan_count: int,
|
|
764
|
+
*,
|
|
765
|
+
latency_percentiles: dict[str, float] | None = None,
|
|
766
|
+
l1_latency_percentiles: dict[str, float] | None = None,
|
|
767
|
+
l2_latency_percentiles: dict[str, float] | None = None,
|
|
768
|
+
memory_usage: dict[str, float] | None = None,
|
|
769
|
+
threat_detection_rate: float | None = None,
|
|
770
|
+
rules_loaded: int | None = None,
|
|
771
|
+
l2_enabled: bool | None = None,
|
|
772
|
+
org_id: str | None = None,
|
|
773
|
+
team_id: str | None = None,
|
|
774
|
+
) -> TelemetryEvent:
|
|
775
|
+
"""Create a performance telemetry event.
|
|
776
|
+
|
|
777
|
+
Aggregated performance metrics (sent periodically).
|
|
778
|
+
|
|
779
|
+
Args:
|
|
780
|
+
period_start: Start of measurement period (ISO 8601).
|
|
781
|
+
period_end: End of measurement period (ISO 8601).
|
|
782
|
+
scan_count: Number of scans in period.
|
|
783
|
+
latency_percentiles: Scan latency distribution (p50_ms, p95_ms, p99_ms, max_ms).
|
|
784
|
+
l1_latency_percentiles: L1 scan latency distribution.
|
|
785
|
+
l2_latency_percentiles: L2 scan latency distribution.
|
|
786
|
+
memory_usage: Memory usage statistics (current_mb, peak_mb).
|
|
787
|
+
threat_detection_rate: Percentage of scans with threats detected (0.0-1.0).
|
|
788
|
+
rules_loaded: Number of rules loaded.
|
|
789
|
+
l2_enabled: Whether L2 ML detection is enabled.
|
|
790
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
791
|
+
team_id: Team ID for team-level analytics.
|
|
792
|
+
|
|
793
|
+
Returns:
|
|
794
|
+
TelemetryEvent with performance payload.
|
|
795
|
+
|
|
796
|
+
Example:
|
|
797
|
+
>>> event = create_performance_event(
|
|
798
|
+
... period_start="2025-01-22T10:00:00Z",
|
|
799
|
+
... period_end="2025-01-22T11:00:00Z",
|
|
800
|
+
... scan_count=1000,
|
|
801
|
+
... latency_percentiles={"p50_ms": 2.5, "p95_ms": 8.0, "p99_ms": 12.0},
|
|
802
|
+
... threat_detection_rate=0.05,
|
|
803
|
+
... org_id="org_123",
|
|
804
|
+
... team_id="team_456",
|
|
805
|
+
... )
|
|
806
|
+
"""
|
|
807
|
+
payload: dict[str, Any] = {
|
|
808
|
+
"period_start": period_start,
|
|
809
|
+
"period_end": period_end,
|
|
810
|
+
"scan_count": scan_count,
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
if latency_percentiles is not None:
|
|
814
|
+
payload["latency_percentiles"] = latency_percentiles
|
|
815
|
+
|
|
816
|
+
if l1_latency_percentiles is not None:
|
|
817
|
+
payload["l1_latency_percentiles"] = l1_latency_percentiles
|
|
818
|
+
|
|
819
|
+
if l2_latency_percentiles is not None:
|
|
820
|
+
payload["l2_latency_percentiles"] = l2_latency_percentiles
|
|
821
|
+
|
|
822
|
+
if memory_usage is not None:
|
|
823
|
+
payload["memory_usage"] = memory_usage
|
|
824
|
+
|
|
825
|
+
if threat_detection_rate is not None:
|
|
826
|
+
payload["threat_detection_rate"] = threat_detection_rate
|
|
827
|
+
|
|
828
|
+
if rules_loaded is not None:
|
|
829
|
+
payload["rules_loaded"] = rules_loaded
|
|
830
|
+
|
|
831
|
+
if l2_enabled is not None:
|
|
832
|
+
payload["l2_enabled"] = l2_enabled
|
|
833
|
+
|
|
834
|
+
return TelemetryEvent(
|
|
835
|
+
event_id=generate_event_id(),
|
|
836
|
+
event_type=EventType.PERFORMANCE.value,
|
|
837
|
+
timestamp=_get_utc_timestamp(),
|
|
838
|
+
priority="standard",
|
|
839
|
+
payload=payload,
|
|
840
|
+
org_id=org_id,
|
|
841
|
+
team_id=team_id,
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
# =============================================================================
|
|
846
|
+
# Feature Usage Event
|
|
847
|
+
# =============================================================================
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
def create_feature_usage_event(
|
|
851
|
+
feature: Literal[
|
|
852
|
+
"cli_scan",
|
|
853
|
+
"cli_rules_list",
|
|
854
|
+
"cli_rules_show",
|
|
855
|
+
"cli_config",
|
|
856
|
+
"cli_stats",
|
|
857
|
+
"cli_repl",
|
|
858
|
+
"cli_explain",
|
|
859
|
+
"cli_validate_rule",
|
|
860
|
+
"cli_doctor",
|
|
861
|
+
"cli_telemetry_dlq",
|
|
862
|
+
"sdk_scan",
|
|
863
|
+
"sdk_batch_scan",
|
|
864
|
+
"sdk_layer_control",
|
|
865
|
+
"wrapper_openai",
|
|
866
|
+
"wrapper_anthropic",
|
|
867
|
+
"integration_langchain",
|
|
868
|
+
"custom_rule_loaded",
|
|
869
|
+
"policy_applied",
|
|
870
|
+
],
|
|
871
|
+
action: Literal["invoked", "completed", "failed", "cancelled"],
|
|
872
|
+
*,
|
|
873
|
+
duration_ms: float | None = None,
|
|
874
|
+
success: bool | None = None,
|
|
875
|
+
metadata: dict[str, Any] | None = None,
|
|
876
|
+
org_id: str | None = None,
|
|
877
|
+
team_id: str | None = None,
|
|
878
|
+
) -> TelemetryEvent:
|
|
879
|
+
"""Create a feature usage telemetry event.
|
|
880
|
+
|
|
881
|
+
Tracks usage of specific features for product analytics.
|
|
882
|
+
|
|
883
|
+
Args:
|
|
884
|
+
feature: Feature being used.
|
|
885
|
+
action: Action taken with feature.
|
|
886
|
+
duration_ms: Time spent using feature.
|
|
887
|
+
success: Whether feature usage was successful.
|
|
888
|
+
metadata: Feature-specific non-sensitive metadata.
|
|
889
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
890
|
+
team_id: Team ID for team-level analytics.
|
|
891
|
+
|
|
892
|
+
Returns:
|
|
893
|
+
TelemetryEvent with feature_usage payload.
|
|
894
|
+
|
|
895
|
+
Example:
|
|
896
|
+
>>> event = create_feature_usage_event(
|
|
897
|
+
... feature="cli_scan",
|
|
898
|
+
... action="completed",
|
|
899
|
+
... duration_ms=150.5,
|
|
900
|
+
... success=True,
|
|
901
|
+
... metadata={"output_format": "json"},
|
|
902
|
+
... org_id="org_123",
|
|
903
|
+
... team_id="team_456",
|
|
904
|
+
... )
|
|
905
|
+
"""
|
|
906
|
+
payload: dict[str, Any] = {
|
|
907
|
+
"feature": feature,
|
|
908
|
+
"action": action,
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
if duration_ms is not None:
|
|
912
|
+
payload["duration_ms"] = duration_ms
|
|
913
|
+
|
|
914
|
+
if success is not None:
|
|
915
|
+
payload["success"] = success
|
|
916
|
+
|
|
917
|
+
if metadata is not None:
|
|
918
|
+
payload["metadata"] = metadata
|
|
919
|
+
|
|
920
|
+
return TelemetryEvent(
|
|
921
|
+
event_id=generate_event_id(),
|
|
922
|
+
event_type=EventType.FEATURE_USAGE.value,
|
|
923
|
+
timestamp=_get_utc_timestamp(),
|
|
924
|
+
priority="standard",
|
|
925
|
+
payload=payload,
|
|
926
|
+
org_id=org_id,
|
|
927
|
+
team_id=team_id,
|
|
928
|
+
)
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
# =============================================================================
|
|
932
|
+
# Heartbeat Event
|
|
933
|
+
# =============================================================================
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
def create_heartbeat_event(
|
|
937
|
+
uptime_seconds: float,
|
|
938
|
+
scans_since_last_heartbeat: int,
|
|
939
|
+
*,
|
|
940
|
+
threats_since_last_heartbeat: int | None = None,
|
|
941
|
+
memory_mb: float | None = None,
|
|
942
|
+
queue_depths: dict[str, int] | None = None,
|
|
943
|
+
circuit_breaker_state: Literal["closed", "open", "half_open"] | None = None,
|
|
944
|
+
last_successful_ship: str | None = None,
|
|
945
|
+
org_id: str | None = None,
|
|
946
|
+
team_id: str | None = None,
|
|
947
|
+
) -> TelemetryEvent:
|
|
948
|
+
"""Create a heartbeat telemetry event.
|
|
949
|
+
|
|
950
|
+
Periodic health signal for long-running processes.
|
|
951
|
+
|
|
952
|
+
Args:
|
|
953
|
+
uptime_seconds: Time since process started.
|
|
954
|
+
scans_since_last_heartbeat: Scans performed since last heartbeat.
|
|
955
|
+
threats_since_last_heartbeat: Threats detected since last heartbeat.
|
|
956
|
+
memory_mb: Current memory usage.
|
|
957
|
+
queue_depths: Current telemetry queue sizes (critical, standard, dlq).
|
|
958
|
+
circuit_breaker_state: Current circuit breaker state.
|
|
959
|
+
last_successful_ship: Timestamp of last successful telemetry ship.
|
|
960
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
961
|
+
team_id: Team ID for team-level analytics.
|
|
962
|
+
|
|
963
|
+
Returns:
|
|
964
|
+
TelemetryEvent with heartbeat payload.
|
|
965
|
+
|
|
966
|
+
Example:
|
|
967
|
+
>>> event = create_heartbeat_event(
|
|
968
|
+
... uptime_seconds=3600.0,
|
|
969
|
+
... scans_since_last_heartbeat=100,
|
|
970
|
+
... threats_since_last_heartbeat=5,
|
|
971
|
+
... memory_mb=120.5,
|
|
972
|
+
... queue_depths={"critical": 0, "standard": 10, "dlq": 2},
|
|
973
|
+
... circuit_breaker_state="closed",
|
|
974
|
+
... org_id="org_123",
|
|
975
|
+
... team_id="team_456",
|
|
976
|
+
... )
|
|
977
|
+
"""
|
|
978
|
+
payload: dict[str, Any] = {
|
|
979
|
+
"uptime_seconds": uptime_seconds,
|
|
980
|
+
"scans_since_last_heartbeat": scans_since_last_heartbeat,
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
if threats_since_last_heartbeat is not None:
|
|
984
|
+
payload["threats_since_last_heartbeat"] = threats_since_last_heartbeat
|
|
985
|
+
|
|
986
|
+
if memory_mb is not None:
|
|
987
|
+
payload["memory_mb"] = memory_mb
|
|
988
|
+
|
|
989
|
+
if queue_depths is not None:
|
|
990
|
+
payload["queue_depths"] = queue_depths
|
|
991
|
+
|
|
992
|
+
if circuit_breaker_state is not None:
|
|
993
|
+
payload["circuit_breaker_state"] = circuit_breaker_state
|
|
994
|
+
|
|
995
|
+
if last_successful_ship is not None:
|
|
996
|
+
payload["last_successful_ship"] = last_successful_ship
|
|
997
|
+
|
|
998
|
+
return TelemetryEvent(
|
|
999
|
+
event_id=generate_event_id(),
|
|
1000
|
+
event_type=EventType.HEARTBEAT.value,
|
|
1001
|
+
timestamp=_get_utc_timestamp(),
|
|
1002
|
+
priority="standard",
|
|
1003
|
+
payload=payload,
|
|
1004
|
+
org_id=org_id,
|
|
1005
|
+
team_id=team_id,
|
|
1006
|
+
)
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
# =============================================================================
|
|
1010
|
+
# Key Upgrade Event
|
|
1011
|
+
# =============================================================================
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
def create_key_upgrade_event(
|
|
1015
|
+
previous_key_type: Literal["temp", "community", "pro", "enterprise"],
|
|
1016
|
+
new_key_type: Literal["community", "pro", "enterprise"],
|
|
1017
|
+
*,
|
|
1018
|
+
previous_key_id: str | None = None,
|
|
1019
|
+
new_key_id: str | None = None,
|
|
1020
|
+
days_on_previous: int | None = None,
|
|
1021
|
+
scans_on_previous: int | None = None,
|
|
1022
|
+
threats_on_previous: int | None = None,
|
|
1023
|
+
conversion_trigger: Literal[
|
|
1024
|
+
"trial_expiry",
|
|
1025
|
+
"rate_limit_hit",
|
|
1026
|
+
"feature_needed",
|
|
1027
|
+
"manual_upgrade",
|
|
1028
|
+
"promo_code",
|
|
1029
|
+
"cli_connect",
|
|
1030
|
+
]
|
|
1031
|
+
| None = None,
|
|
1032
|
+
org_id: str | None = None,
|
|
1033
|
+
team_id: str | None = None,
|
|
1034
|
+
) -> TelemetryEvent:
|
|
1035
|
+
"""Create a key upgrade telemetry event.
|
|
1036
|
+
|
|
1037
|
+
Fired when API key is upgraded (conversion tracking). Includes key IDs
|
|
1038
|
+
to enable server-side linking of historical events from the old key
|
|
1039
|
+
to the new key.
|
|
1040
|
+
|
|
1041
|
+
Args:
|
|
1042
|
+
previous_key_type: Previous key tier.
|
|
1043
|
+
new_key_type: New key tier.
|
|
1044
|
+
previous_key_id: BigQuery-compatible ID for previous key (e.g., "key_23cc2f9f21f9").
|
|
1045
|
+
Computed as "key_" + SHA256(api_key)[:12].
|
|
1046
|
+
new_key_id: BigQuery-compatible ID for new key (e.g., "key_7ce219b525f1").
|
|
1047
|
+
Computed as "key_" + SHA256(api_key)[:12].
|
|
1048
|
+
days_on_previous: Days spent on previous tier.
|
|
1049
|
+
scans_on_previous: Total scans on previous tier.
|
|
1050
|
+
threats_on_previous: Total threats detected on previous tier.
|
|
1051
|
+
conversion_trigger: What triggered the upgrade.
|
|
1052
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
1053
|
+
team_id: Team ID for team-level analytics.
|
|
1054
|
+
|
|
1055
|
+
Returns:
|
|
1056
|
+
TelemetryEvent with key_upgrade payload.
|
|
1057
|
+
|
|
1058
|
+
Example:
|
|
1059
|
+
>>> event = create_key_upgrade_event(
|
|
1060
|
+
... previous_key_type="temp",
|
|
1061
|
+
... new_key_type="community",
|
|
1062
|
+
... previous_key_id="key_23cc2f9f21f9",
|
|
1063
|
+
... new_key_id="key_7ce219b525f1",
|
|
1064
|
+
... days_on_previous=7,
|
|
1065
|
+
... scans_on_previous=500,
|
|
1066
|
+
... threats_on_previous=25,
|
|
1067
|
+
... conversion_trigger="trial_expiry",
|
|
1068
|
+
... org_id="org_123",
|
|
1069
|
+
... team_id="team_456",
|
|
1070
|
+
... )
|
|
1071
|
+
"""
|
|
1072
|
+
payload: dict[str, Any] = {
|
|
1073
|
+
"previous_key_type": previous_key_type,
|
|
1074
|
+
"new_key_type": new_key_type,
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
# Add key IDs for server-side event linking
|
|
1078
|
+
if previous_key_id is not None:
|
|
1079
|
+
payload["previous_key_id"] = previous_key_id
|
|
1080
|
+
|
|
1081
|
+
if new_key_id is not None:
|
|
1082
|
+
payload["new_key_id"] = new_key_id
|
|
1083
|
+
|
|
1084
|
+
if days_on_previous is not None:
|
|
1085
|
+
payload["days_on_previous"] = days_on_previous
|
|
1086
|
+
|
|
1087
|
+
if scans_on_previous is not None:
|
|
1088
|
+
payload["scans_on_previous"] = scans_on_previous
|
|
1089
|
+
|
|
1090
|
+
if threats_on_previous is not None:
|
|
1091
|
+
payload["threats_on_previous"] = threats_on_previous
|
|
1092
|
+
|
|
1093
|
+
if conversion_trigger is not None:
|
|
1094
|
+
payload["conversion_trigger"] = conversion_trigger
|
|
1095
|
+
|
|
1096
|
+
return TelemetryEvent(
|
|
1097
|
+
event_id=generate_event_id(),
|
|
1098
|
+
event_type=EventType.KEY_UPGRADE.value,
|
|
1099
|
+
timestamp=_get_utc_timestamp(),
|
|
1100
|
+
priority="critical",
|
|
1101
|
+
payload=payload,
|
|
1102
|
+
org_id=org_id,
|
|
1103
|
+
team_id=team_id,
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
# =============================================================================
|
|
1108
|
+
# Config Changed Event
|
|
1109
|
+
# =============================================================================
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
def create_config_changed_event(
|
|
1113
|
+
changed_via: Literal["cli", "sdk", "config_file", "env_var"],
|
|
1114
|
+
changes: list[dict[str, Any]],
|
|
1115
|
+
*,
|
|
1116
|
+
is_final_event: bool = False,
|
|
1117
|
+
org_id: str | None = None,
|
|
1118
|
+
team_id: str | None = None,
|
|
1119
|
+
) -> TelemetryEvent:
|
|
1120
|
+
"""Create a config changed telemetry event.
|
|
1121
|
+
|
|
1122
|
+
Fired when configuration is changed (tracks opt-outs and preferences).
|
|
1123
|
+
|
|
1124
|
+
Args:
|
|
1125
|
+
changed_via: How configuration was changed.
|
|
1126
|
+
changes: List of configuration changes. Each change should have:
|
|
1127
|
+
- key: Configuration key that changed (e.g., "telemetry.enabled")
|
|
1128
|
+
- new_value: New value
|
|
1129
|
+
- old_value: Previous value (optional)
|
|
1130
|
+
is_final_event: True if this is the last event before telemetry disable.
|
|
1131
|
+
org_id: Organization ID for multi-tenant tracking.
|
|
1132
|
+
team_id: Team ID for team-level analytics.
|
|
1133
|
+
|
|
1134
|
+
Returns:
|
|
1135
|
+
TelemetryEvent with config_changed payload. Priority is critical
|
|
1136
|
+
if telemetry is being disabled (is_final_event=True), otherwise standard.
|
|
1137
|
+
|
|
1138
|
+
Example:
|
|
1139
|
+
>>> event = create_config_changed_event(
|
|
1140
|
+
... changed_via="cli",
|
|
1141
|
+
... changes=[
|
|
1142
|
+
... {"key": "telemetry.enabled", "old_value": True, "new_value": False}
|
|
1143
|
+
... ],
|
|
1144
|
+
... is_final_event=True,
|
|
1145
|
+
... org_id="org_123",
|
|
1146
|
+
... team_id="team_456",
|
|
1147
|
+
... )
|
|
1148
|
+
"""
|
|
1149
|
+
payload: dict[str, Any] = {
|
|
1150
|
+
"changed_via": changed_via,
|
|
1151
|
+
"changes": changes,
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
if is_final_event:
|
|
1155
|
+
payload["is_final_event"] = is_final_event
|
|
1156
|
+
|
|
1157
|
+
# Priority is critical if disabling telemetry (is_final_event=True)
|
|
1158
|
+
priority: Literal["critical", "standard"] = "critical" if is_final_event else "standard"
|
|
1159
|
+
|
|
1160
|
+
return TelemetryEvent(
|
|
1161
|
+
event_id=generate_event_id(),
|
|
1162
|
+
event_type=EventType.CONFIG_CHANGED.value,
|
|
1163
|
+
timestamp=_get_utc_timestamp(),
|
|
1164
|
+
priority=priority,
|
|
1165
|
+
payload=payload,
|
|
1166
|
+
org_id=org_id,
|
|
1167
|
+
team_id=team_id,
|
|
1168
|
+
)
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
# =============================================================================
|
|
1172
|
+
# Team Invite Event
|
|
1173
|
+
# =============================================================================
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
def create_team_invite_event(
|
|
1177
|
+
inviter_installation_id: str,
|
|
1178
|
+
invitee_email_hash: str,
|
|
1179
|
+
org_id: str,
|
|
1180
|
+
team_id: str,
|
|
1181
|
+
role: Literal["admin", "member", "viewer"],
|
|
1182
|
+
*,
|
|
1183
|
+
invite_method: Literal["email", "link", "api"] = "email",
|
|
1184
|
+
) -> TelemetryEvent:
|
|
1185
|
+
"""Create a team invite telemetry event.
|
|
1186
|
+
|
|
1187
|
+
Tracks team invitations for viral growth metrics.
|
|
1188
|
+
|
|
1189
|
+
Args:
|
|
1190
|
+
inviter_installation_id: Installation ID of the user sending the invite.
|
|
1191
|
+
invitee_email_hash: SHA-256 hash of invitee's email (privacy-preserving).
|
|
1192
|
+
org_id: Organization identifier.
|
|
1193
|
+
team_id: Team identifier within the organization.
|
|
1194
|
+
role: Role being assigned to the invitee.
|
|
1195
|
+
invite_method: How the invitation was sent.
|
|
1196
|
+
|
|
1197
|
+
Returns:
|
|
1198
|
+
TelemetryEvent with team_invite payload (critical priority).
|
|
1199
|
+
|
|
1200
|
+
Example:
|
|
1201
|
+
>>> event = create_team_invite_event(
|
|
1202
|
+
... inviter_installation_id="inst_abc123def456789",
|
|
1203
|
+
... invitee_email_hash="a" * 64,
|
|
1204
|
+
... org_id="org_123",
|
|
1205
|
+
... team_id="team_456",
|
|
1206
|
+
... role="member",
|
|
1207
|
+
... invite_method="email",
|
|
1208
|
+
... )
|
|
1209
|
+
"""
|
|
1210
|
+
payload: dict[str, Any] = {
|
|
1211
|
+
"inviter_installation_id": inviter_installation_id,
|
|
1212
|
+
"invitee_email_hash": invitee_email_hash,
|
|
1213
|
+
"org_id": org_id,
|
|
1214
|
+
"team_id": team_id,
|
|
1215
|
+
"role": role,
|
|
1216
|
+
"invite_method": invite_method,
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
return TelemetryEvent(
|
|
1220
|
+
event_id=generate_event_id(),
|
|
1221
|
+
event_type=EventType.TEAM_INVITE.value,
|
|
1222
|
+
timestamp=_get_utc_timestamp(),
|
|
1223
|
+
priority="critical",
|
|
1224
|
+
payload=payload,
|
|
1225
|
+
org_id=org_id,
|
|
1226
|
+
team_id=team_id,
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
# =============================================================================
|
|
1231
|
+
# Utility Functions
|
|
1232
|
+
# =============================================================================
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
def create_prompt_hash(prompt: str) -> str:
|
|
1236
|
+
"""Create a SHA-256 hash of a prompt for telemetry.
|
|
1237
|
+
|
|
1238
|
+
This is a convenience wrapper around hash_text for scan events.
|
|
1239
|
+
|
|
1240
|
+
Args:
|
|
1241
|
+
prompt: The prompt text to hash.
|
|
1242
|
+
|
|
1243
|
+
Returns:
|
|
1244
|
+
71-character prefixed SHA-256 hash string (sha256:<64_hex_chars>).
|
|
1245
|
+
|
|
1246
|
+
Example:
|
|
1247
|
+
>>> create_prompt_hash("Hello, world!")
|
|
1248
|
+
'sha256:315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3'
|
|
1249
|
+
"""
|
|
1250
|
+
return hash_text(prompt, algorithm="sha256")
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
def event_to_dict(event: TelemetryEvent) -> dict[str, Any]:
|
|
1254
|
+
"""Convert a TelemetryEvent to a dictionary for serialization.
|
|
1255
|
+
|
|
1256
|
+
Args:
|
|
1257
|
+
event: The telemetry event to convert.
|
|
1258
|
+
|
|
1259
|
+
Returns:
|
|
1260
|
+
Dictionary representation of the event including org_id and team_id if present.
|
|
1261
|
+
|
|
1262
|
+
Example:
|
|
1263
|
+
>>> event = create_heartbeat_event(uptime_seconds=100.0, scans_since_last_heartbeat=5)
|
|
1264
|
+
>>> d = event_to_dict(event)
|
|
1265
|
+
>>> d["event_type"]
|
|
1266
|
+
'heartbeat'
|
|
1267
|
+
"""
|
|
1268
|
+
result: dict[str, Any] = {
|
|
1269
|
+
"event_id": event.event_id,
|
|
1270
|
+
"event_type": event.event_type,
|
|
1271
|
+
"timestamp": event.timestamp,
|
|
1272
|
+
"priority": event.priority,
|
|
1273
|
+
"payload": event.payload,
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
if event.org_id is not None:
|
|
1277
|
+
result["org_id"] = event.org_id
|
|
1278
|
+
|
|
1279
|
+
if event.team_id is not None:
|
|
1280
|
+
result["team_id"] = event.team_id
|
|
1281
|
+
|
|
1282
|
+
return result
|