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,786 @@
|
|
|
1
|
+
"""Model registry for managing multiple L2 models.
|
|
2
|
+
|
|
3
|
+
Provides auto-discovery, selection, and comparison of L2 models.
|
|
4
|
+
Supports multiple model types (ONNX INT8, PyTorch, etc.) with
|
|
5
|
+
zero code changes to add new models.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import TYPE_CHECKING, Literal
|
|
13
|
+
|
|
14
|
+
from raxe.domain.ml.model_metadata import ModelMetadata, ModelStatus
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from raxe.domain.ml.protocol import L2Detector
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ModelRegistry:
|
|
23
|
+
"""Registry for L2 models with auto-discovery.
|
|
24
|
+
|
|
25
|
+
Automatically discovers all .raxe model files in the models directory
|
|
26
|
+
and loads their metadata from JSON files.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
registry = ModelRegistry()
|
|
30
|
+
|
|
31
|
+
# List all models
|
|
32
|
+
models = registry.list_models()
|
|
33
|
+
|
|
34
|
+
# Get specific model
|
|
35
|
+
model = registry.get_model("v1.0_onnx_int8")
|
|
36
|
+
|
|
37
|
+
# Get best model for criteria
|
|
38
|
+
fastest = registry.get_best_model("latency")
|
|
39
|
+
|
|
40
|
+
# Create detector
|
|
41
|
+
detector = registry.create_detector("v1.0_onnx_int8")
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self, models_dir: Path | None = None):
|
|
45
|
+
"""Initialize registry.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
models_dir: Optional custom models directory
|
|
49
|
+
(default: src/raxe/domain/ml/models)
|
|
50
|
+
"""
|
|
51
|
+
if models_dir is None:
|
|
52
|
+
# Default to package models directory
|
|
53
|
+
models_dir = Path(__file__).parent / "models"
|
|
54
|
+
|
|
55
|
+
self.models_dir = models_dir
|
|
56
|
+
self._models: dict[str, ModelMetadata] = {}
|
|
57
|
+
self._discover_models()
|
|
58
|
+
|
|
59
|
+
def _discover_models(self) -> None:
|
|
60
|
+
"""Auto-discover all models using three-tier priority discovery.
|
|
61
|
+
|
|
62
|
+
Discovery Priority:
|
|
63
|
+
1. Manifest-based models (manifest.yaml in subdirectories) - HIGHEST
|
|
64
|
+
2. .raxe files in models/ root directory - MEDIUM
|
|
65
|
+
3. metadata/*.json files - LOWEST (legacy)
|
|
66
|
+
|
|
67
|
+
This ensures manifest-based models take precedence while maintaining
|
|
68
|
+
backward compatibility with existing .raxe and JSON-based models.
|
|
69
|
+
"""
|
|
70
|
+
if not self.models_dir.exists():
|
|
71
|
+
logger.warning(f"Models directory not found: {self.models_dir}")
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
discovery_stats = {
|
|
75
|
+
"manifest": 0,
|
|
76
|
+
"raxe_root": 0,
|
|
77
|
+
"metadata_json": 0,
|
|
78
|
+
"errors": 0
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# PRIORITY 1: Discover manifest-based models from subdirectories
|
|
82
|
+
manifest_models = self._discover_manifest_models()
|
|
83
|
+
for model_id, metadata in manifest_models.items():
|
|
84
|
+
self._models[model_id] = metadata
|
|
85
|
+
discovery_stats["manifest"] += 1
|
|
86
|
+
|
|
87
|
+
# PRIORITY 2: Discover from .raxe files in root (if not already loaded)
|
|
88
|
+
raxe_files = list(self.models_dir.glob("*.raxe"))
|
|
89
|
+
if raxe_files:
|
|
90
|
+
logger.info(f"Discovered {len(raxe_files)} .raxe files in {self.models_dir}")
|
|
91
|
+
|
|
92
|
+
for raxe_file in raxe_files:
|
|
93
|
+
try:
|
|
94
|
+
# Extract model_id from filename
|
|
95
|
+
# Format: raxe_model_l2_{version}_{variant}.raxe
|
|
96
|
+
# Example: raxe_model_l2_v1.0_onnx_int8.raxe -> v1.0_onnx_int8
|
|
97
|
+
filename = raxe_file.stem # Without .raxe extension
|
|
98
|
+
if filename.startswith("raxe_model_l2_"):
|
|
99
|
+
model_id = filename.replace("raxe_model_l2_", "")
|
|
100
|
+
else:
|
|
101
|
+
# Fallback: use full filename as ID
|
|
102
|
+
model_id = filename
|
|
103
|
+
|
|
104
|
+
# Skip if already loaded from manifest
|
|
105
|
+
if model_id in self._models:
|
|
106
|
+
logger.debug(f"Skipping {model_id} (already loaded from manifest)")
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
# Try to load metadata JSON
|
|
110
|
+
metadata_dir = self.models_dir / "metadata"
|
|
111
|
+
metadata_file = metadata_dir / f"{model_id}.json"
|
|
112
|
+
|
|
113
|
+
if metadata_file.exists():
|
|
114
|
+
# Load from JSON
|
|
115
|
+
with open(metadata_file) as f:
|
|
116
|
+
data = json.load(f)
|
|
117
|
+
metadata = ModelMetadata.from_dict(data, file_path=raxe_file)
|
|
118
|
+
logger.info(f"Loaded model: {model_id} ({metadata.name})")
|
|
119
|
+
else:
|
|
120
|
+
# Create minimal metadata from filename
|
|
121
|
+
metadata = self._create_default_metadata(model_id, raxe_file)
|
|
122
|
+
logger.info(f"No metadata file for {model_id}, using defaults")
|
|
123
|
+
|
|
124
|
+
self._models[model_id] = metadata
|
|
125
|
+
discovery_stats["raxe_root"] += 1
|
|
126
|
+
|
|
127
|
+
except Exception as e:
|
|
128
|
+
logger.error(f"Failed to load model {raxe_file.name}: {e}")
|
|
129
|
+
discovery_stats["errors"] += 1
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
# PRIORITY 3: Discover from metadata files (for variants that share bundle files)
|
|
133
|
+
metadata_dir = self.models_dir / "metadata"
|
|
134
|
+
if metadata_dir.exists():
|
|
135
|
+
metadata_files = list(metadata_dir.glob("*.json"))
|
|
136
|
+
for metadata_file in metadata_files:
|
|
137
|
+
try:
|
|
138
|
+
model_id = metadata_file.stem
|
|
139
|
+
|
|
140
|
+
# Skip if already loaded from manifest or .raxe file
|
|
141
|
+
if model_id in self._models:
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
# Load metadata
|
|
145
|
+
with open(metadata_file) as f:
|
|
146
|
+
data = json.load(f)
|
|
147
|
+
|
|
148
|
+
# Resolve bundle file path
|
|
149
|
+
bundle_filename = data["file_info"]["filename"]
|
|
150
|
+
bundle_path = self.models_dir / bundle_filename
|
|
151
|
+
|
|
152
|
+
if not bundle_path.exists():
|
|
153
|
+
logger.warning(f"Bundle file not found for {model_id}: {bundle_path}")
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
# Load model with correct bundle path
|
|
157
|
+
metadata = ModelMetadata.from_dict(data, file_path=bundle_path)
|
|
158
|
+
logger.info(f"Loaded model from metadata: {model_id} ({metadata.name})")
|
|
159
|
+
self._models[model_id] = metadata
|
|
160
|
+
discovery_stats["metadata_json"] += 1
|
|
161
|
+
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.error(f"Failed to load model from metadata {metadata_file.name}: {e}")
|
|
164
|
+
discovery_stats["errors"] += 1
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
# Log discovery summary
|
|
168
|
+
total = discovery_stats["manifest"] + discovery_stats["raxe_root"] + discovery_stats["metadata_json"]
|
|
169
|
+
if total > 0:
|
|
170
|
+
logger.info(
|
|
171
|
+
f"Model discovery complete: {total} models loaded "
|
|
172
|
+
f"(manifest={discovery_stats['manifest']}, "
|
|
173
|
+
f"raxe={discovery_stats['raxe_root']}, "
|
|
174
|
+
f"json={discovery_stats['metadata_json']}, "
|
|
175
|
+
f"errors={discovery_stats['errors']})"
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
logger.warning(f"No models discovered in {self.models_dir}")
|
|
179
|
+
|
|
180
|
+
def _create_default_metadata(
|
|
181
|
+
self,
|
|
182
|
+
model_id: str,
|
|
183
|
+
file_path: Path
|
|
184
|
+
) -> ModelMetadata:
|
|
185
|
+
"""Create default metadata for model without JSON file."""
|
|
186
|
+
from raxe.domain.ml.model_metadata import (
|
|
187
|
+
FileInfo,
|
|
188
|
+
ModelRuntime,
|
|
189
|
+
ModelStatus,
|
|
190
|
+
PerformanceMetrics,
|
|
191
|
+
Requirements,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Guess runtime from model_id
|
|
195
|
+
if "onnx_int8" in model_id:
|
|
196
|
+
runtime = ModelRuntime.ONNX_INT8
|
|
197
|
+
elif "onnx" in model_id:
|
|
198
|
+
runtime = ModelRuntime.ONNX
|
|
199
|
+
elif "pytorch" in model_id:
|
|
200
|
+
runtime = ModelRuntime.PYTORCH
|
|
201
|
+
else:
|
|
202
|
+
runtime = ModelRuntime.CUSTOM
|
|
203
|
+
|
|
204
|
+
# Get file size
|
|
205
|
+
size_mb = file_path.stat().st_size / (1024 * 1024) if file_path.exists() else 0
|
|
206
|
+
|
|
207
|
+
return ModelMetadata(
|
|
208
|
+
model_id=model_id,
|
|
209
|
+
name=f"RAXE L2 {model_id}",
|
|
210
|
+
version="unknown",
|
|
211
|
+
variant=model_id,
|
|
212
|
+
description=f"L2 model {model_id} (auto-discovered, no metadata file)",
|
|
213
|
+
file_info=FileInfo(
|
|
214
|
+
filename=file_path.name,
|
|
215
|
+
size_mb=size_mb,
|
|
216
|
+
),
|
|
217
|
+
performance=PerformanceMetrics(
|
|
218
|
+
target_latency_ms=50.0, # Conservative default
|
|
219
|
+
),
|
|
220
|
+
requirements=Requirements(runtime=runtime),
|
|
221
|
+
status=ModelStatus.EXPERIMENTAL, # Mark as experimental without metadata
|
|
222
|
+
file_path=file_path,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
def _discover_manifest_models(self) -> dict[str, ModelMetadata]:
|
|
226
|
+
"""Discover models from manifest.yaml files in subdirectories.
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Dictionary mapping model_id to ModelMetadata
|
|
230
|
+
"""
|
|
231
|
+
models = {}
|
|
232
|
+
|
|
233
|
+
# Find all subdirectories with manifest.yaml
|
|
234
|
+
for item in self.models_dir.iterdir():
|
|
235
|
+
if not item.is_dir():
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
manifest_file = item / "manifest.yaml"
|
|
239
|
+
if not manifest_file.exists():
|
|
240
|
+
continue
|
|
241
|
+
|
|
242
|
+
try:
|
|
243
|
+
# Load manifest
|
|
244
|
+
model = self._load_manifest_model(item, manifest_file)
|
|
245
|
+
if model:
|
|
246
|
+
models[model.model_id] = model
|
|
247
|
+
logger.info(f"Loaded manifest model: {model.model_id} from {item.name}")
|
|
248
|
+
|
|
249
|
+
except Exception as e:
|
|
250
|
+
logger.error(f"Failed to load manifest model from {item.name}: {e}")
|
|
251
|
+
continue
|
|
252
|
+
|
|
253
|
+
return models
|
|
254
|
+
|
|
255
|
+
def _load_manifest_model(
|
|
256
|
+
self,
|
|
257
|
+
folder: Path,
|
|
258
|
+
manifest_file: Path
|
|
259
|
+
) -> ModelMetadata | None:
|
|
260
|
+
"""Load model from manifest file.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
folder: Model folder path
|
|
264
|
+
manifest_file: Path to manifest.yaml
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
ModelMetadata or None if loading failed
|
|
268
|
+
"""
|
|
269
|
+
from raxe.domain.ml.manifest_loader import ManifestLoader
|
|
270
|
+
|
|
271
|
+
# Load manifest
|
|
272
|
+
loader = ManifestLoader(strict=False) # Non-strict for graceful degradation
|
|
273
|
+
manifest_data = loader.load_manifest(manifest_file)
|
|
274
|
+
|
|
275
|
+
# Extract model_id from folder name or manifest
|
|
276
|
+
model_id = manifest_data.get("model_id") or folder.name
|
|
277
|
+
|
|
278
|
+
# ADAPTATION: Support both bundle and ONNX manifest formats
|
|
279
|
+
manifest_data = self._adapt_manifest_format(manifest_data)
|
|
280
|
+
|
|
281
|
+
# Validate tokenizer if present
|
|
282
|
+
if manifest_data.get("tokenizer"):
|
|
283
|
+
is_valid, errors = self._validate_tokenizer(manifest_data)
|
|
284
|
+
if not is_valid:
|
|
285
|
+
logger.warning(
|
|
286
|
+
f"Tokenizer validation warnings for {model_id}:\n" +
|
|
287
|
+
"\n".join(f" - {err}" for err in errors)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Convert manifest to metadata
|
|
291
|
+
return self._manifest_to_metadata(manifest_data, folder)
|
|
292
|
+
|
|
293
|
+
def _adapt_manifest_format(self, manifest: dict) -> dict:
|
|
294
|
+
"""Adapt ONNX manifest format to bundle format for compatibility.
|
|
295
|
+
|
|
296
|
+
Supports three manifest formats:
|
|
297
|
+
1. Bundle format: model.bundle_file points to .raxe file
|
|
298
|
+
2. Legacy ONNX format: file_info.filename points to .onnx file
|
|
299
|
+
3. ONNX-only format: onnx_files section with separate ONNX models
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
manifest: Original manifest data
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Adapted manifest in bundle-compatible format
|
|
306
|
+
"""
|
|
307
|
+
# If already in bundle format, return as-is
|
|
308
|
+
if "model" in manifest and "bundle_file" in manifest.get("model", {}):
|
|
309
|
+
return manifest
|
|
310
|
+
|
|
311
|
+
# NEW: Handle ONNX-only format (manifest v2.0)
|
|
312
|
+
if manifest.get("model_type") == "onnx_only" or "onnx_files" in manifest:
|
|
313
|
+
adapted = manifest.copy()
|
|
314
|
+
adapted["is_onnx_only"] = True # Flag for detector creation
|
|
315
|
+
|
|
316
|
+
# Extract model runtime info
|
|
317
|
+
runtime = "onnx"
|
|
318
|
+
if manifest.get("metadata", {}).get("quantization") == "int8":
|
|
319
|
+
runtime = "onnx_int8"
|
|
320
|
+
elif manifest.get("metadata", {}).get("quantization") == "fp16":
|
|
321
|
+
runtime = "onnx_fp16"
|
|
322
|
+
|
|
323
|
+
# Create model section for compatibility
|
|
324
|
+
adapted["model"] = {
|
|
325
|
+
"runtime": runtime,
|
|
326
|
+
"model_type": "onnx_only",
|
|
327
|
+
# No bundle_file for ONNX-only models
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
# Keep onnx_files section
|
|
331
|
+
if "onnx_files" in manifest:
|
|
332
|
+
adapted["model"]["onnx_files"] = manifest["onnx_files"]
|
|
333
|
+
|
|
334
|
+
return adapted
|
|
335
|
+
|
|
336
|
+
# If in legacy ONNX format, adapt it
|
|
337
|
+
if "file_info" in manifest:
|
|
338
|
+
adapted = manifest.copy()
|
|
339
|
+
|
|
340
|
+
# Move metadata.status to root level
|
|
341
|
+
if "metadata" in manifest and "status" in manifest["metadata"]:
|
|
342
|
+
adapted["status"] = manifest["metadata"]["status"]
|
|
343
|
+
|
|
344
|
+
# Create model section from file_info
|
|
345
|
+
file_info = manifest["file_info"]
|
|
346
|
+
filename = file_info.get("filename", "")
|
|
347
|
+
|
|
348
|
+
# Determine runtime from filename
|
|
349
|
+
runtime = "onnx"
|
|
350
|
+
if "int8" in filename.lower():
|
|
351
|
+
runtime = "onnx_int8"
|
|
352
|
+
elif "fp16" in filename.lower():
|
|
353
|
+
runtime = "onnx_fp16"
|
|
354
|
+
|
|
355
|
+
adapted["model"] = {
|
|
356
|
+
"bundle_file": filename,
|
|
357
|
+
"runtime": runtime,
|
|
358
|
+
# Store original ONNX file reference
|
|
359
|
+
"onnx_embeddings": filename,
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
# Add embedding model if in metadata
|
|
363
|
+
if "metadata" in manifest:
|
|
364
|
+
base_model = manifest["metadata"].get("base_model")
|
|
365
|
+
if base_model:
|
|
366
|
+
adapted["model"]["embedding_model"] = base_model
|
|
367
|
+
|
|
368
|
+
# Adapt tokenizer structure
|
|
369
|
+
if "tokenizer" in manifest:
|
|
370
|
+
tok = manifest["tokenizer"]
|
|
371
|
+
tokenizer_class = tok.get("tokenizer_class", "AutoTokenizer")
|
|
372
|
+
adapted["tokenizer"] = {
|
|
373
|
+
"name": tok.get("tokenizer_name", tok.get("hf_model_id", "")),
|
|
374
|
+
"type": tokenizer_class,
|
|
375
|
+
"config": {
|
|
376
|
+
"type": tokenizer_class, # Add type to config as well
|
|
377
|
+
"max_length": tok.get("max_length", 512),
|
|
378
|
+
"model_max_length": tok.get("model_max_length", 512),
|
|
379
|
+
"do_lower_case": tok.get("do_lower_case", False),
|
|
380
|
+
"padding_side": tok.get("padding_side", "right"),
|
|
381
|
+
"truncation_side": tok.get("truncation_side", "right"),
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return adapted
|
|
386
|
+
|
|
387
|
+
# Unknown format, return as-is
|
|
388
|
+
return manifest
|
|
389
|
+
|
|
390
|
+
def _validate_tokenizer(self, manifest: dict) -> tuple[bool, list[str]]:
|
|
391
|
+
"""Validate tokenizer configuration in manifest.
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
manifest: Manifest data dictionary
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
Tuple of (is_valid, error_messages)
|
|
398
|
+
"""
|
|
399
|
+
from raxe.domain.ml.tokenizer_registry import get_tokenizer_registry
|
|
400
|
+
|
|
401
|
+
errors = []
|
|
402
|
+
|
|
403
|
+
tokenizer_data = manifest.get("tokenizer")
|
|
404
|
+
if not tokenizer_data:
|
|
405
|
+
return True, [] # No tokenizer, nothing to validate
|
|
406
|
+
|
|
407
|
+
# Check required fields
|
|
408
|
+
tokenizer_name = tokenizer_data.get("name")
|
|
409
|
+
if not tokenizer_name:
|
|
410
|
+
errors.append("Tokenizer name is required")
|
|
411
|
+
|
|
412
|
+
# Check compatibility with embedding model
|
|
413
|
+
model_data = manifest.get("model", {})
|
|
414
|
+
embedding_model = model_data.get("embedding_model")
|
|
415
|
+
|
|
416
|
+
if tokenizer_name and embedding_model:
|
|
417
|
+
registry = get_tokenizer_registry()
|
|
418
|
+
is_compat = registry.is_compatible(tokenizer_name, embedding_model)
|
|
419
|
+
if not is_compat:
|
|
420
|
+
errors.append(
|
|
421
|
+
f"Tokenizer '{tokenizer_name}' may not be compatible "
|
|
422
|
+
f"with embedding model '{embedding_model}'"
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
# Validate full tokenizer config
|
|
426
|
+
tokenizer_config = tokenizer_data.get("config", {})
|
|
427
|
+
_is_valid, validation_errors = registry.validate_tokenizer(
|
|
428
|
+
tokenizer_name,
|
|
429
|
+
tokenizer_config,
|
|
430
|
+
embedding_model
|
|
431
|
+
)
|
|
432
|
+
errors.extend(validation_errors)
|
|
433
|
+
|
|
434
|
+
return len(errors) == 0, errors
|
|
435
|
+
|
|
436
|
+
def _manifest_to_metadata(
|
|
437
|
+
self,
|
|
438
|
+
manifest: dict,
|
|
439
|
+
folder: Path
|
|
440
|
+
) -> ModelMetadata:
|
|
441
|
+
"""Convert manifest data to ModelMetadata.
|
|
442
|
+
|
|
443
|
+
Args:
|
|
444
|
+
manifest: Manifest data dictionary
|
|
445
|
+
folder: Model folder path
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
ModelMetadata instance
|
|
449
|
+
"""
|
|
450
|
+
from raxe.domain.ml.model_metadata import (
|
|
451
|
+
AccuracyMetrics,
|
|
452
|
+
FileInfo,
|
|
453
|
+
ModelRuntime,
|
|
454
|
+
ModelStatus,
|
|
455
|
+
PerformanceMetrics,
|
|
456
|
+
Requirements,
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
# Extract basic fields
|
|
460
|
+
model_id = manifest.get("model_id") or folder.name
|
|
461
|
+
name = manifest.get("name", f"RAXE L2 {model_id}")
|
|
462
|
+
version = manifest.get("version", "0.0.1")
|
|
463
|
+
variant = manifest.get("variant", model_id)
|
|
464
|
+
description = manifest.get("description", "")
|
|
465
|
+
status = ModelStatus(manifest.get("status", "experimental"))
|
|
466
|
+
|
|
467
|
+
# Extract model section
|
|
468
|
+
model_data = manifest.get("model", {})
|
|
469
|
+
is_onnx_only = manifest.get("is_onnx_only", False) or model_data.get("model_type") == "onnx_only"
|
|
470
|
+
|
|
471
|
+
# Handle different model types
|
|
472
|
+
if is_onnx_only:
|
|
473
|
+
# ONNX-only: no bundle file, use folder size
|
|
474
|
+
bundle_filename = ""
|
|
475
|
+
bundle_path = None
|
|
476
|
+
|
|
477
|
+
# Calculate total size of ONNX files
|
|
478
|
+
size_mb = 0.0
|
|
479
|
+
for onnx_file in folder.glob("*.onnx"):
|
|
480
|
+
size_mb += onnx_file.stat().st_size / (1024 * 1024)
|
|
481
|
+
else:
|
|
482
|
+
# Bundle-based model
|
|
483
|
+
bundle_filename = model_data.get("bundle_file", "")
|
|
484
|
+
bundle_path = folder / bundle_filename if bundle_filename else None
|
|
485
|
+
|
|
486
|
+
# Get bundle size if exists
|
|
487
|
+
size_mb = 0.0
|
|
488
|
+
if bundle_path and bundle_path.exists():
|
|
489
|
+
size_mb = bundle_path.stat().st_size / (1024 * 1024)
|
|
490
|
+
|
|
491
|
+
# Extract file info
|
|
492
|
+
file_info = FileInfo(
|
|
493
|
+
filename=bundle_filename if bundle_filename else folder.name, # Use folder name for ONNX-only
|
|
494
|
+
size_mb=size_mb,
|
|
495
|
+
onnx_embeddings=model_data.get("onnx_embeddings"),
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
# Extract performance
|
|
499
|
+
perf_data = manifest.get("performance", {})
|
|
500
|
+
performance = PerformanceMetrics(
|
|
501
|
+
target_latency_ms=perf_data.get("target_latency_ms", 50.0),
|
|
502
|
+
p50_latency_ms=perf_data.get("p50_latency_ms"),
|
|
503
|
+
p95_latency_ms=perf_data.get("p95_latency_ms"),
|
|
504
|
+
p99_latency_ms=perf_data.get("p99_latency_ms"),
|
|
505
|
+
memory_mb=perf_data.get("memory_mb"),
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
# Extract accuracy
|
|
509
|
+
acc_data = manifest.get("accuracy", {})
|
|
510
|
+
accuracy = None
|
|
511
|
+
if acc_data:
|
|
512
|
+
accuracy = AccuracyMetrics(
|
|
513
|
+
binary_f1=acc_data.get("binary_f1"),
|
|
514
|
+
family_f1=acc_data.get("family_f1"),
|
|
515
|
+
subfamily_f1=acc_data.get("subfamily_f1"),
|
|
516
|
+
false_positive_rate=acc_data.get("false_positive_rate"),
|
|
517
|
+
false_negative_rate=acc_data.get("false_negative_rate"),
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
# Determine runtime from model data
|
|
521
|
+
runtime_str = model_data.get("runtime", "onnx")
|
|
522
|
+
try:
|
|
523
|
+
runtime = ModelRuntime(runtime_str)
|
|
524
|
+
except ValueError:
|
|
525
|
+
runtime = ModelRuntime.ONNX # Default fallback
|
|
526
|
+
|
|
527
|
+
requirements = Requirements(runtime=runtime)
|
|
528
|
+
|
|
529
|
+
# Extract tokenizer fields
|
|
530
|
+
tokenizer_data = manifest.get("tokenizer")
|
|
531
|
+
tokenizer_name = None
|
|
532
|
+
tokenizer_config = None
|
|
533
|
+
if tokenizer_data:
|
|
534
|
+
tokenizer_name = tokenizer_data.get("name")
|
|
535
|
+
tokenizer_config = tokenizer_data.get("config")
|
|
536
|
+
|
|
537
|
+
embedding_model_name = model_data.get("embedding_model")
|
|
538
|
+
|
|
539
|
+
# Extract tags
|
|
540
|
+
tags = manifest.get("tags", [])
|
|
541
|
+
|
|
542
|
+
# Determine file_path based on model type
|
|
543
|
+
if is_onnx_only:
|
|
544
|
+
# For ONNX-only models, file_path is the folder
|
|
545
|
+
file_path_to_use = folder
|
|
546
|
+
else:
|
|
547
|
+
# For bundle models, file_path is the bundle file
|
|
548
|
+
file_path_to_use = bundle_path
|
|
549
|
+
|
|
550
|
+
return ModelMetadata(
|
|
551
|
+
model_id=model_id,
|
|
552
|
+
name=name,
|
|
553
|
+
version=version,
|
|
554
|
+
variant=variant,
|
|
555
|
+
description=description,
|
|
556
|
+
file_info=file_info,
|
|
557
|
+
performance=performance,
|
|
558
|
+
requirements=requirements,
|
|
559
|
+
status=status,
|
|
560
|
+
accuracy=accuracy,
|
|
561
|
+
tags=tags,
|
|
562
|
+
tokenizer_name=tokenizer_name,
|
|
563
|
+
tokenizer_config=tokenizer_config,
|
|
564
|
+
embedding_model_name=embedding_model_name,
|
|
565
|
+
file_path=file_path_to_use, # Folder for ONNX-only, file for bundles
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
def list_models(
|
|
569
|
+
self,
|
|
570
|
+
status: ModelStatus | None = None,
|
|
571
|
+
runtime: str | None = None
|
|
572
|
+
) -> list[ModelMetadata]:
|
|
573
|
+
"""List all discovered models.
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
status: Optional filter by status (active, experimental, deprecated)
|
|
577
|
+
runtime: Optional filter by runtime type
|
|
578
|
+
|
|
579
|
+
Returns:
|
|
580
|
+
List of model metadata, sorted by model_id
|
|
581
|
+
"""
|
|
582
|
+
models = list(self._models.values())
|
|
583
|
+
|
|
584
|
+
# Filter by status
|
|
585
|
+
if status:
|
|
586
|
+
models = [m for m in models if m.status == status]
|
|
587
|
+
|
|
588
|
+
# Filter by runtime
|
|
589
|
+
if runtime:
|
|
590
|
+
models = [m for m in models if m.runtime_type == runtime]
|
|
591
|
+
|
|
592
|
+
# Sort by model_id
|
|
593
|
+
models.sort(key=lambda m: m.model_id)
|
|
594
|
+
|
|
595
|
+
return models
|
|
596
|
+
|
|
597
|
+
def get_model(self, model_id: str) -> ModelMetadata | None:
|
|
598
|
+
"""Get specific model by ID.
|
|
599
|
+
|
|
600
|
+
Args:
|
|
601
|
+
model_id: Model identifier (e.g., "v1.0_onnx_int8")
|
|
602
|
+
|
|
603
|
+
Returns:
|
|
604
|
+
Model metadata or None if not found
|
|
605
|
+
"""
|
|
606
|
+
return self._models.get(model_id)
|
|
607
|
+
|
|
608
|
+
def has_model(self, model_id: str) -> bool:
|
|
609
|
+
"""Check if model exists.
|
|
610
|
+
|
|
611
|
+
Args:
|
|
612
|
+
model_id: Model identifier
|
|
613
|
+
|
|
614
|
+
Returns:
|
|
615
|
+
True if model exists
|
|
616
|
+
"""
|
|
617
|
+
return model_id in self._models
|
|
618
|
+
|
|
619
|
+
def get_best_model(
|
|
620
|
+
self,
|
|
621
|
+
criteria: Literal["latency", "accuracy", "balanced", "memory"] = "balanced"
|
|
622
|
+
) -> ModelMetadata | None:
|
|
623
|
+
"""Get best model based on criteria.
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
criteria: Selection criteria:
|
|
627
|
+
- "latency": Fastest model
|
|
628
|
+
- "accuracy": Most accurate model
|
|
629
|
+
- "balanced": Best balance of speed and accuracy
|
|
630
|
+
- "memory": Smallest memory footprint
|
|
631
|
+
|
|
632
|
+
Returns:
|
|
633
|
+
Best model or None if no models available
|
|
634
|
+
"""
|
|
635
|
+
# Only consider active models
|
|
636
|
+
active_models = self.list_models(status=ModelStatus.ACTIVE)
|
|
637
|
+
|
|
638
|
+
if not active_models:
|
|
639
|
+
# Fall back to any model
|
|
640
|
+
active_models = self.list_models()
|
|
641
|
+
|
|
642
|
+
if not active_models:
|
|
643
|
+
return None
|
|
644
|
+
|
|
645
|
+
# Score each model and pick best
|
|
646
|
+
best_model = None
|
|
647
|
+
best_score = -1
|
|
648
|
+
|
|
649
|
+
for model in active_models:
|
|
650
|
+
score = model.score_for_criteria(criteria)
|
|
651
|
+
if score > best_score:
|
|
652
|
+
best_score = score
|
|
653
|
+
best_model = model
|
|
654
|
+
|
|
655
|
+
return best_model
|
|
656
|
+
|
|
657
|
+
def create_detector(
|
|
658
|
+
self,
|
|
659
|
+
model_id: str | None = None,
|
|
660
|
+
criteria: str | None = None,
|
|
661
|
+
voting_preset: str | None = None,
|
|
662
|
+
) -> L2Detector:
|
|
663
|
+
"""Create detector from model.
|
|
664
|
+
|
|
665
|
+
Args:
|
|
666
|
+
model_id: Specific model to use, or None to auto-select
|
|
667
|
+
criteria: Auto-selection criteria if model_id not specified
|
|
668
|
+
voting_preset: Voting preset override (balanced, high_security, low_fp)
|
|
669
|
+
|
|
670
|
+
Returns:
|
|
671
|
+
L2Detector instance
|
|
672
|
+
|
|
673
|
+
Raises:
|
|
674
|
+
ValueError: If model not found
|
|
675
|
+
"""
|
|
676
|
+
# Auto-select if no model_id specified
|
|
677
|
+
if model_id is None:
|
|
678
|
+
criteria = criteria or "balanced"
|
|
679
|
+
model = self.get_best_model(criteria) # type: ignore
|
|
680
|
+
if not model:
|
|
681
|
+
raise ValueError("No models available")
|
|
682
|
+
model_id = model.model_id
|
|
683
|
+
logger.info(f"Auto-selected model '{model_id}' (criteria: {criteria})")
|
|
684
|
+
|
|
685
|
+
# Get model metadata
|
|
686
|
+
model = self.get_model(model_id)
|
|
687
|
+
if not model:
|
|
688
|
+
raise ValueError(f"Model not found: {model_id}")
|
|
689
|
+
|
|
690
|
+
# Get model file path
|
|
691
|
+
if model.file_path:
|
|
692
|
+
model_file = model.file_path
|
|
693
|
+
else:
|
|
694
|
+
# Fallback: look in models directory
|
|
695
|
+
model_file = self.models_dir / model.file_info.filename
|
|
696
|
+
|
|
697
|
+
if not model_file.exists():
|
|
698
|
+
raise ValueError(f"Model file not found: {model_file}")
|
|
699
|
+
|
|
700
|
+
# Get ONNX embeddings path if specified
|
|
701
|
+
onnx_path = None
|
|
702
|
+
if model.file_info.onnx_embeddings:
|
|
703
|
+
onnx_path = self.models_dir / model.file_info.onnx_embeddings
|
|
704
|
+
if not onnx_path.exists():
|
|
705
|
+
logger.warning(f"ONNX embeddings not found: {onnx_path}, falling back to sentence-transformers")
|
|
706
|
+
onnx_path = None
|
|
707
|
+
|
|
708
|
+
# Extract tokenizer config if present
|
|
709
|
+
tokenizer_config = None
|
|
710
|
+
if model.tokenizer_config:
|
|
711
|
+
tokenizer_config = model.tokenizer_config.copy()
|
|
712
|
+
# Add tokenizer name for ONNX embedder
|
|
713
|
+
if model.tokenizer_name:
|
|
714
|
+
tokenizer_config["tokenizer_name"] = model.tokenizer_name
|
|
715
|
+
|
|
716
|
+
# Check if this is a folder-based model (ONNX-only)
|
|
717
|
+
if model_file.is_dir():
|
|
718
|
+
# This is a folder-based Gemma model
|
|
719
|
+
from raxe.domain.ml.gemma_detector import create_gemma_detector
|
|
720
|
+
from raxe.domain.ml.l2_config import get_l2_config
|
|
721
|
+
|
|
722
|
+
l2_config = get_l2_config()
|
|
723
|
+
logger.info(f"Creating Gemma detector from folder: {model_id} ({model_file.name})")
|
|
724
|
+
return create_gemma_detector(
|
|
725
|
+
model_dir=str(model_file),
|
|
726
|
+
confidence_threshold=l2_config.thresholds.threat_threshold,
|
|
727
|
+
voting_preset=voting_preset,
|
|
728
|
+
)
|
|
729
|
+
else:
|
|
730
|
+
# File-based models not supported (only folder-based ONNX models)
|
|
731
|
+
raise ValueError(
|
|
732
|
+
f"Model {model_id} points to a file ({model_file.name}), not a folder. "
|
|
733
|
+
f"Only folder-based Gemma ONNX models are supported."
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
def compare_models(
|
|
737
|
+
self,
|
|
738
|
+
model_ids: list[str] | None = None
|
|
739
|
+
) -> dict[str, ModelMetadata]:
|
|
740
|
+
"""Compare multiple models.
|
|
741
|
+
|
|
742
|
+
Args:
|
|
743
|
+
model_ids: List of model IDs to compare, or None for all active models
|
|
744
|
+
|
|
745
|
+
Returns:
|
|
746
|
+
Dictionary mapping model_id to metadata
|
|
747
|
+
"""
|
|
748
|
+
if model_ids:
|
|
749
|
+
# Compare specific models
|
|
750
|
+
models = {}
|
|
751
|
+
for model_id in model_ids:
|
|
752
|
+
model = self.get_model(model_id)
|
|
753
|
+
if model:
|
|
754
|
+
models[model_id] = model
|
|
755
|
+
else:
|
|
756
|
+
logger.warning(f"Model not found: {model_id}")
|
|
757
|
+
else:
|
|
758
|
+
# Compare all active models
|
|
759
|
+
active_models = self.list_models(status=ModelStatus.ACTIVE)
|
|
760
|
+
models = {m.model_id: m for m in active_models}
|
|
761
|
+
|
|
762
|
+
return models
|
|
763
|
+
|
|
764
|
+
def get_model_count(self) -> int:
|
|
765
|
+
"""Get total number of discovered models."""
|
|
766
|
+
return len(self._models)
|
|
767
|
+
|
|
768
|
+
def get_active_model_count(self) -> int:
|
|
769
|
+
"""Get number of active (production-ready) models."""
|
|
770
|
+
return len(self.list_models(status=ModelStatus.ACTIVE))
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
# Global registry instance (lazy initialized)
|
|
774
|
+
_registry: ModelRegistry | None = None
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
def get_registry() -> ModelRegistry:
|
|
778
|
+
"""Get global model registry instance.
|
|
779
|
+
|
|
780
|
+
Returns:
|
|
781
|
+
Singleton ModelRegistry instance
|
|
782
|
+
"""
|
|
783
|
+
global _registry
|
|
784
|
+
if _registry is None:
|
|
785
|
+
_registry = ModelRegistry()
|
|
786
|
+
return _registry
|