crca 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .github/ISSUE_TEMPLATE/bug_report.md +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +41 -0
- .github/PULL_REQUEST_TEMPLATE.md +20 -0
- .github/workflows/publish-manual.yml +61 -0
- .github/workflows/publish.yml +64 -0
- .gitignore +214 -0
- CRCA.py +4156 -0
- LICENSE +201 -0
- MANIFEST.in +43 -0
- PKG-INFO +5035 -0
- README.md +4959 -0
- __init__.py +17 -0
- branches/CRCA-Q.py +2728 -0
- branches/crca_cg/corposwarm.py +9065 -0
- branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
- branches/crca_cg/package.json +5 -0
- branches/crca_cg/test_bolt_integration.py +446 -0
- branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
- branches/crca_cg/test_new_features.py +163 -0
- branches/crca_sd/__init__.py +149 -0
- branches/crca_sd/crca_sd_core.py +770 -0
- branches/crca_sd/crca_sd_governance.py +1325 -0
- branches/crca_sd/crca_sd_mpc.py +1130 -0
- branches/crca_sd/crca_sd_realtime.py +1844 -0
- branches/crca_sd/crca_sd_tui.py +1133 -0
- crca-1.4.0.dist-info/METADATA +5035 -0
- crca-1.4.0.dist-info/RECORD +501 -0
- crca-1.4.0.dist-info/WHEEL +4 -0
- crca-1.4.0.dist-info/licenses/LICENSE +201 -0
- docs/CRCA-Q.md +2333 -0
- examples/config.yaml.example +25 -0
- examples/crca_sd_example.py +513 -0
- examples/data_broker_example.py +294 -0
- examples/logistics_corporation.py +861 -0
- examples/palantir_example.py +299 -0
- examples/policy_bench.py +934 -0
- examples/pridnestrovia-sd.py +705 -0
- examples/pridnestrovia_realtime.py +1902 -0
- prompts/__init__.py +10 -0
- prompts/default_crca.py +101 -0
- pyproject.toml +151 -0
- requirements.txt +76 -0
- schemas/__init__.py +43 -0
- schemas/mcpSchemas.py +51 -0
- schemas/policy.py +458 -0
- templates/__init__.py +38 -0
- templates/base_specialized_agent.py +195 -0
- templates/drift_detection.py +325 -0
- templates/examples/causal_agent_template.py +309 -0
- templates/examples/drag_drop_example.py +213 -0
- templates/examples/logistics_agent_template.py +207 -0
- templates/examples/trading_agent_template.py +206 -0
- templates/feature_mixins.py +253 -0
- templates/graph_management.py +442 -0
- templates/llm_integration.py +194 -0
- templates/module_registry.py +276 -0
- templates/mpc_planner.py +280 -0
- templates/policy_loop.py +1168 -0
- templates/prediction_framework.py +448 -0
- templates/statistical_methods.py +778 -0
- tests/sanity.yml +31 -0
- tests/sanity_check +406 -0
- tests/test_core.py +47 -0
- tests/test_crca_excel.py +166 -0
- tests/test_crca_sd.py +780 -0
- tests/test_data_broker.py +424 -0
- tests/test_palantir.py +349 -0
- tools/__init__.py +38 -0
- tools/actuators.py +437 -0
- tools/bolt.diy/Dockerfile +103 -0
- tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
- tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
- tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
- tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
- tools/bolt.diy/app/components/@settings/index.ts +12 -0
- tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
- tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
- tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
- tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
- tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
- tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
- tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
- tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
- tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
- tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
- tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
- tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
- tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
- tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
- tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
- tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
- tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
- tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
- tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
- tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
- tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
- tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
- tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
- tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
- tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
- tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
- tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
- tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
- tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
- tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
- tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
- tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
- tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
- tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
- tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
- tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
- tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
- tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
- tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
- tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
- tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
- tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
- tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
- tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
- tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
- tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
- tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
- tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
- tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
- tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
- tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
- tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
- tools/bolt.diy/app/components/header/Header.tsx +42 -0
- tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
- tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
- tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
- tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
- tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
- tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
- tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
- tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
- tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
- tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
- tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
- tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
- tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
- tools/bolt.diy/app/components/txt +1 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
- tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
- tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
- tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
- tools/bolt.diy/app/components/ui/Button.tsx +46 -0
- tools/bolt.diy/app/components/ui/Card.tsx +55 -0
- tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
- tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
- tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
- tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
- tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
- tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
- tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
- tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
- tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
- tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
- tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
- tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
- tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
- tools/bolt.diy/app/components/ui/Input.tsx +22 -0
- tools/bolt.diy/app/components/ui/Label.tsx +20 -0
- tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
- tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
- tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
- tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
- tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
- tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
- tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
- tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
- tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
- tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
- tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
- tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
- tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
- tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
- tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
- tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
- tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
- tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
- tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
- tools/bolt.diy/app/components/ui/index.ts +38 -0
- tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
- tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
- tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
- tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
- tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
- tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
- tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
- tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
- tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
- tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
- tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
- tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
- tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
- tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
- tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
- tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
- tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
- tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
- tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
- tools/bolt.diy/app/entry.client.tsx +7 -0
- tools/bolt.diy/app/entry.server.tsx +80 -0
- tools/bolt.diy/app/root.tsx +156 -0
- tools/bolt.diy/app/routes/_index.tsx +175 -0
- tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
- tools/bolt.diy/app/routes/api.chat.ts +463 -0
- tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
- tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
- tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
- tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
- tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
- tools/bolt.diy/app/routes/api.git-info.ts +69 -0
- tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
- tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
- tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
- tools/bolt.diy/app/routes/api.github-template.ts +242 -0
- tools/bolt.diy/app/routes/api.github-user.ts +287 -0
- tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
- tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
- tools/bolt.diy/app/routes/api.health.ts +8 -0
- tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
- tools/bolt.diy/app/routes/api.mandate.ts +351 -0
- tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
- tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
- tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
- tools/bolt.diy/app/routes/api.models.ts +90 -0
- tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
- tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
- tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
- tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
- tools/bolt.diy/app/routes/api.supabase.ts +56 -0
- tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
- tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
- tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
- tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
- tools/bolt.diy/app/routes/api.update.ts +21 -0
- tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
- tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
- tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
- tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
- tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
- tools/bolt.diy/app/routes/git.tsx +25 -0
- tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
- tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
- tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
- tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
- tools/bolt.diy/app/styles/animations.scss +49 -0
- tools/bolt.diy/app/styles/components/code.scss +9 -0
- tools/bolt.diy/app/styles/components/editor.scss +135 -0
- tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
- tools/bolt.diy/app/styles/components/terminal.scss +3 -0
- tools/bolt.diy/app/styles/components/toast.scss +23 -0
- tools/bolt.diy/app/styles/diff-view.css +72 -0
- tools/bolt.diy/app/styles/index.scss +73 -0
- tools/bolt.diy/app/styles/variables.scss +255 -0
- tools/bolt.diy/app/styles/z-index.scss +37 -0
- tools/bolt.diy/app/types/GitHub.ts +182 -0
- tools/bolt.diy/app/types/GitLab.ts +103 -0
- tools/bolt.diy/app/types/actions.ts +85 -0
- tools/bolt.diy/app/types/artifact.ts +5 -0
- tools/bolt.diy/app/types/context.ts +26 -0
- tools/bolt.diy/app/types/design-scheme.ts +93 -0
- tools/bolt.diy/app/types/global.d.ts +13 -0
- tools/bolt.diy/app/types/mandate.ts +333 -0
- tools/bolt.diy/app/types/model.ts +25 -0
- tools/bolt.diy/app/types/netlify.ts +94 -0
- tools/bolt.diy/app/types/supabase.ts +54 -0
- tools/bolt.diy/app/types/template.ts +8 -0
- tools/bolt.diy/app/types/terminal.ts +9 -0
- tools/bolt.diy/app/types/theme.ts +1 -0
- tools/bolt.diy/app/types/vercel.ts +67 -0
- tools/bolt.diy/app/utils/buffer.ts +29 -0
- tools/bolt.diy/app/utils/classNames.ts +65 -0
- tools/bolt.diy/app/utils/constants.ts +147 -0
- tools/bolt.diy/app/utils/debounce.ts +13 -0
- tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
- tools/bolt.diy/app/utils/diff.spec.ts +11 -0
- tools/bolt.diy/app/utils/diff.ts +117 -0
- tools/bolt.diy/app/utils/easings.ts +3 -0
- tools/bolt.diy/app/utils/fileLocks.ts +96 -0
- tools/bolt.diy/app/utils/fileUtils.ts +121 -0
- tools/bolt.diy/app/utils/folderImport.ts +73 -0
- tools/bolt.diy/app/utils/formatSize.ts +12 -0
- tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
- tools/bolt.diy/app/utils/githubStats.ts +9 -0
- tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
- tools/bolt.diy/app/utils/logger.ts +162 -0
- tools/bolt.diy/app/utils/markdown.ts +155 -0
- tools/bolt.diy/app/utils/mobile.ts +4 -0
- tools/bolt.diy/app/utils/os.ts +4 -0
- tools/bolt.diy/app/utils/path.ts +19 -0
- tools/bolt.diy/app/utils/projectCommands.ts +197 -0
- tools/bolt.diy/app/utils/promises.ts +19 -0
- tools/bolt.diy/app/utils/react.ts +6 -0
- tools/bolt.diy/app/utils/sampler.ts +49 -0
- tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
- tools/bolt.diy/app/utils/shell.ts +384 -0
- tools/bolt.diy/app/utils/stacktrace.ts +27 -0
- tools/bolt.diy/app/utils/stripIndent.ts +23 -0
- tools/bolt.diy/app/utils/terminal.ts +11 -0
- tools/bolt.diy/app/utils/unreachable.ts +3 -0
- tools/bolt.diy/app/vite-env.d.ts +2 -0
- tools/bolt.diy/assets/entitlements.mac.plist +25 -0
- tools/bolt.diy/assets/icons/icon.icns +0 -0
- tools/bolt.diy/assets/icons/icon.ico +0 -0
- tools/bolt.diy/assets/icons/icon.png +0 -0
- tools/bolt.diy/bindings.js +78 -0
- tools/bolt.diy/bindings.sh +33 -0
- tools/bolt.diy/docker-compose.yaml +145 -0
- tools/bolt.diy/electron/main/index.ts +201 -0
- tools/bolt.diy/electron/main/tsconfig.json +30 -0
- tools/bolt.diy/electron/main/ui/menu.ts +29 -0
- tools/bolt.diy/electron/main/ui/window.ts +54 -0
- tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
- tools/bolt.diy/electron/main/utils/constants.ts +4 -0
- tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
- tools/bolt.diy/electron/main/utils/reload.ts +35 -0
- tools/bolt.diy/electron/main/utils/serve.ts +71 -0
- tools/bolt.diy/electron/main/utils/store.ts +3 -0
- tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
- tools/bolt.diy/electron/main/vite.config.ts +44 -0
- tools/bolt.diy/electron/preload/index.ts +22 -0
- tools/bolt.diy/electron/preload/tsconfig.json +7 -0
- tools/bolt.diy/electron/preload/vite.config.ts +31 -0
- tools/bolt.diy/electron-builder.yml +64 -0
- tools/bolt.diy/electron-update.yml +4 -0
- tools/bolt.diy/eslint.config.mjs +57 -0
- tools/bolt.diy/functions/[[path]].ts +12 -0
- tools/bolt.diy/icons/angular.svg +1 -0
- tools/bolt.diy/icons/astro.svg +8 -0
- tools/bolt.diy/icons/chat.svg +1 -0
- tools/bolt.diy/icons/expo-brand.svg +1 -0
- tools/bolt.diy/icons/expo.svg +4 -0
- tools/bolt.diy/icons/logo-text.svg +1 -0
- tools/bolt.diy/icons/logo.svg +4 -0
- tools/bolt.diy/icons/mcp.svg +1 -0
- tools/bolt.diy/icons/nativescript.svg +1 -0
- tools/bolt.diy/icons/netlify.svg +10 -0
- tools/bolt.diy/icons/nextjs.svg +1 -0
- tools/bolt.diy/icons/nuxt.svg +1 -0
- tools/bolt.diy/icons/qwik.svg +1 -0
- tools/bolt.diy/icons/react.svg +1 -0
- tools/bolt.diy/icons/remix.svg +24 -0
- tools/bolt.diy/icons/remotion.svg +1 -0
- tools/bolt.diy/icons/shadcn.svg +21 -0
- tools/bolt.diy/icons/slidev.svg +60 -0
- tools/bolt.diy/icons/solidjs.svg +1 -0
- tools/bolt.diy/icons/stars.svg +1 -0
- tools/bolt.diy/icons/svelte.svg +1 -0
- tools/bolt.diy/icons/typescript.svg +1 -0
- tools/bolt.diy/icons/vite.svg +1 -0
- tools/bolt.diy/icons/vue.svg +1 -0
- tools/bolt.diy/load-context.ts +9 -0
- tools/bolt.diy/notarize.cjs +31 -0
- tools/bolt.diy/package.json +218 -0
- tools/bolt.diy/playwright.config.preview.ts +35 -0
- tools/bolt.diy/pre-start.cjs +26 -0
- tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
- tools/bolt.diy/public/apple-touch-icon.png +0 -0
- tools/bolt.diy/public/favicon.ico +0 -0
- tools/bolt.diy/public/favicon.svg +4 -0
- tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
- tools/bolt.diy/public/icons/Anthropic.svg +4 -0
- tools/bolt.diy/public/icons/Cohere.svg +4 -0
- tools/bolt.diy/public/icons/Deepseek.svg +5 -0
- tools/bolt.diy/public/icons/Default.svg +4 -0
- tools/bolt.diy/public/icons/Google.svg +4 -0
- tools/bolt.diy/public/icons/Groq.svg +4 -0
- tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
- tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
- tools/bolt.diy/public/icons/LMStudio.svg +5 -0
- tools/bolt.diy/public/icons/Mistral.svg +4 -0
- tools/bolt.diy/public/icons/Ollama.svg +4 -0
- tools/bolt.diy/public/icons/OpenAI.svg +4 -0
- tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
- tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
- tools/bolt.diy/public/icons/Perplexity.svg +4 -0
- tools/bolt.diy/public/icons/Together.svg +4 -0
- tools/bolt.diy/public/icons/xAI.svg +5 -0
- tools/bolt.diy/public/inspector-script.js +292 -0
- tools/bolt.diy/public/logo-dark-styled.png +0 -0
- tools/bolt.diy/public/logo-dark.png +0 -0
- tools/bolt.diy/public/logo-light-styled.png +0 -0
- tools/bolt.diy/public/logo-light.png +0 -0
- tools/bolt.diy/public/logo.svg +15 -0
- tools/bolt.diy/public/social_preview_index.jpg +0 -0
- tools/bolt.diy/scripts/clean.js +45 -0
- tools/bolt.diy/scripts/electron-dev.mjs +181 -0
- tools/bolt.diy/scripts/setup-env.sh +41 -0
- tools/bolt.diy/scripts/update-imports.sh +7 -0
- tools/bolt.diy/scripts/update.sh +52 -0
- tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
- tools/bolt.diy/services/execution-governor/config.ts +42 -0
- tools/bolt.diy/services/execution-governor/index.ts +683 -0
- tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
- tools/bolt.diy/services/execution-governor/package.json +31 -0
- tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
- tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
- tools/bolt.diy/services/execution-governor/types.ts +145 -0
- tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
- tools/bolt.diy/services/headless-executor/executor.ts +210 -0
- tools/bolt.diy/services/headless-executor/index.ts +323 -0
- tools/bolt.diy/services/headless-executor/package.json +27 -0
- tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
- tools/bolt.diy/services/headless-executor/types.ts +38 -0
- tools/bolt.diy/test-workflows.sh +240 -0
- tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
- tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
- tools/bolt.diy/tests/mandates/complex.json +53 -0
- tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
- tools/bolt.diy/tests/mandates/simple.json +35 -0
- tools/bolt.diy/tsconfig.json +37 -0
- tools/bolt.diy/types/istextorbinary.d.ts +15 -0
- tools/bolt.diy/uno.config.ts +279 -0
- tools/bolt.diy/vite-electron.config.ts +76 -0
- tools/bolt.diy/vite.config.ts +112 -0
- tools/bolt.diy/worker-configuration.d.ts +22 -0
- tools/bolt.diy/wrangler.toml +6 -0
- tools/code_generator.py +461 -0
- tools/file_operations.py +465 -0
- tools/mandate_generator.py +337 -0
- tools/mcpClientUtils.py +1216 -0
- tools/sensors.py +285 -0
- utils/Agent_types.py +15 -0
- utils/AnyToStr.py +0 -0
- utils/HHCS.py +277 -0
- utils/__init__.py +30 -0
- utils/agent.py +3627 -0
- utils/aop.py +2948 -0
- utils/canonical.py +143 -0
- utils/conversation.py +1195 -0
- utils/doctrine_versioning +230 -0
- utils/formatter.py +474 -0
- utils/ledger.py +311 -0
- utils/out_types.py +16 -0
- utils/rollback.py +339 -0
- utils/router.py +929 -0
- utils/tui.py +1908 -0
examples/policy_bench.py
ADDED
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Advanced Policy Engine Features Demo & Benchmark
|
|
3
|
+
|
|
4
|
+
This example demonstrates and benchmarks all advanced features:
|
|
5
|
+
1. Real sensors/actuators (SystemMetricsSensor, SystemControlActuator)
|
|
6
|
+
2. MPC planning (convex optimization)
|
|
7
|
+
3. Ruptures-based drift detection
|
|
8
|
+
4. Doctrine versioning
|
|
9
|
+
5. Rollback mechanism
|
|
10
|
+
6. LLM integration with ML-assisted decision making
|
|
11
|
+
|
|
12
|
+
Includes performance benchmarks for each feature and demonstrates how
|
|
13
|
+
CRCA's machine learning capabilities assist LLM-based policy decisions.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
import tempfile
|
|
19
|
+
import time
|
|
20
|
+
from datetime import datetime, timedelta, timezone
|
|
21
|
+
from typing import Dict, List, Any, Optional
|
|
22
|
+
import numpy as np
|
|
23
|
+
from loguru import logger
|
|
24
|
+
|
|
25
|
+
# Configure logging
|
|
26
|
+
logger.remove()
|
|
27
|
+
logger.add(lambda msg: print(msg, end=""), format="{message}", level="INFO")
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
from CRCA import CRCAAgent
|
|
31
|
+
from schemas.policy import (
|
|
32
|
+
DoctrineV1, EpochConfig, MetricSpec, Objective, Invariant,
|
|
33
|
+
LeverSpec, RiskBudget
|
|
34
|
+
)
|
|
35
|
+
from tools.sensors import SensorRegistry, SystemMetricsSensor
|
|
36
|
+
from tools.actuators import ActuatorRegistry, SystemControlActuator
|
|
37
|
+
from utils.doctrine_versioning import DoctrineRegistry, register_doctrine
|
|
38
|
+
IMPORTS_AVAILABLE = True
|
|
39
|
+
except ImportError as e:
|
|
40
|
+
print(f"Import error: {e}")
|
|
41
|
+
IMPORTS_AVAILABLE = False
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class BenchmarkTimer:
|
|
45
|
+
"""Context manager for timing operations."""
|
|
46
|
+
|
|
47
|
+
def __init__(self, name: str):
|
|
48
|
+
self.name = name
|
|
49
|
+
self.start_time = None
|
|
50
|
+
self.end_time = None
|
|
51
|
+
|
|
52
|
+
def __enter__(self):
|
|
53
|
+
self.start_time = time.perf_counter()
|
|
54
|
+
return self
|
|
55
|
+
|
|
56
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
57
|
+
self.end_time = time.perf_counter()
|
|
58
|
+
elapsed = self.end_time - self.start_time
|
|
59
|
+
print(f" TIMER {self.name}: {elapsed*1000:.2f} ms")
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def elapsed(self):
|
|
64
|
+
if self.start_time and self.end_time:
|
|
65
|
+
return self.end_time - self.start_time
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class SyntheticEnvironment:
|
|
70
|
+
"""Synthetic environment for testing without real system changes."""
|
|
71
|
+
|
|
72
|
+
def __init__(self, seed: int = 42):
|
|
73
|
+
self.rng = np.random.default_rng(seed)
|
|
74
|
+
self.state = {
|
|
75
|
+
"cpu_usage": 50.0,
|
|
76
|
+
"memory_usage": 60.0,
|
|
77
|
+
"disk_io": 10.0,
|
|
78
|
+
"network_io": 5.0
|
|
79
|
+
}
|
|
80
|
+
self.intervention_history: List[Dict[str, Any]] = []
|
|
81
|
+
|
|
82
|
+
def get_snapshot(self) -> Dict[str, float]:
|
|
83
|
+
"""Get current state snapshot with some noise."""
|
|
84
|
+
# Add small random variations
|
|
85
|
+
snapshot = {
|
|
86
|
+
"cpu_usage": max(0, min(100, self.state["cpu_usage"] + self.rng.normal(0, 2))),
|
|
87
|
+
"memory_usage": max(0, min(100, self.state["memory_usage"] + self.rng.normal(0, 2))),
|
|
88
|
+
"disk_io": max(0, self.state["disk_io"] + self.rng.normal(0, 0.5)),
|
|
89
|
+
"network_io": max(0, self.state["network_io"] + self.rng.normal(0, 0.5))
|
|
90
|
+
}
|
|
91
|
+
return snapshot
|
|
92
|
+
|
|
93
|
+
def apply_intervention(self, intervention: Dict[str, Any]) -> Dict[str, Any]:
|
|
94
|
+
"""Apply intervention and return result."""
|
|
95
|
+
lever_id = intervention.get("lever_id")
|
|
96
|
+
params = intervention.get("parameters", {})
|
|
97
|
+
|
|
98
|
+
result = {"status": "success"}
|
|
99
|
+
|
|
100
|
+
if lever_id == "cpu_throttle":
|
|
101
|
+
# Simulate CPU throttling effect
|
|
102
|
+
throttle_amount = params.get("throttle_percent", 0)
|
|
103
|
+
self.state["cpu_usage"] = max(0, self.state["cpu_usage"] - throttle_amount * 0.5)
|
|
104
|
+
result["cpu_reduction"] = throttle_amount * 0.5
|
|
105
|
+
elif lever_id == "memory_cleanup":
|
|
106
|
+
# Simulate memory cleanup
|
|
107
|
+
cleanup_amount = params.get("cleanup_percent", 0)
|
|
108
|
+
self.state["memory_usage"] = max(0, self.state["memory_usage"] - cleanup_amount * 0.3)
|
|
109
|
+
result["memory_reduction"] = cleanup_amount * 0.3
|
|
110
|
+
|
|
111
|
+
self.intervention_history.append({
|
|
112
|
+
"intervention": intervention,
|
|
113
|
+
"result": result,
|
|
114
|
+
"timestamp": datetime.now(timezone.utc).isoformat()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
return result
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def create_advanced_doctrine() -> DoctrineV1:
|
|
121
|
+
"""Create a doctrine for advanced features demo."""
|
|
122
|
+
return DoctrineV1(
|
|
123
|
+
epoch=EpochConfig(unit="seconds", length=1.0, timezone="UTC"),
|
|
124
|
+
metrics={
|
|
125
|
+
"cpu_usage": MetricSpec(extractor_key="cpu_usage", unit="percent", description="CPU usage percentage"),
|
|
126
|
+
"memory_usage": MetricSpec(extractor_key="memory_usage", unit="percent", description="Memory usage percentage"),
|
|
127
|
+
"disk_io": MetricSpec(extractor_key="disk_io", unit="MB/s", description="Disk I/O rate"),
|
|
128
|
+
"network_io": MetricSpec(extractor_key="network_io", unit="MB/s", description="Network I/O rate")
|
|
129
|
+
},
|
|
130
|
+
objectives=[
|
|
131
|
+
Objective(metric_name="cpu_usage", direction="minimize", weight=2.0, deadline_epoch=10),
|
|
132
|
+
Objective(metric_name="memory_usage", direction="minimize", weight=1.5, deadline_epoch=15),
|
|
133
|
+
Objective(metric_name="disk_io", direction="minimize", weight=1.0)
|
|
134
|
+
],
|
|
135
|
+
invariants=[
|
|
136
|
+
Invariant(
|
|
137
|
+
name="cpu_safety",
|
|
138
|
+
condition="cpu_usage < 95",
|
|
139
|
+
description="CPU must never exceed 95%"
|
|
140
|
+
)
|
|
141
|
+
],
|
|
142
|
+
levers={
|
|
143
|
+
"cpu_throttle": LeverSpec(
|
|
144
|
+
lever_type="ThrottleCPU",
|
|
145
|
+
bounds={"throttle_percent": {"min": 0.0, "max": 50.0}},
|
|
146
|
+
cost_function="throttle_percent * 0.1",
|
|
147
|
+
rollback_required=True,
|
|
148
|
+
description="Throttle CPU usage"
|
|
149
|
+
),
|
|
150
|
+
"memory_cleanup": LeverSpec(
|
|
151
|
+
lever_type="CleanupMemory",
|
|
152
|
+
bounds={"cleanup_percent": {"min": 0.0, "max": 30.0}},
|
|
153
|
+
cost_function="cleanup_percent * 0.05",
|
|
154
|
+
rollback_required=False,
|
|
155
|
+
description="Clean up memory"
|
|
156
|
+
)
|
|
157
|
+
},
|
|
158
|
+
risk_budget=RiskBudget(
|
|
159
|
+
max_actions_per_epoch=3,
|
|
160
|
+
max_risk_per_epoch=2.0,
|
|
161
|
+
rollback_required=True
|
|
162
|
+
),
|
|
163
|
+
version="1.0.0",
|
|
164
|
+
created_at=datetime.now(timezone.utc).isoformat()
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def benchmark_sensors():
|
|
169
|
+
"""Benchmark sensor operations."""
|
|
170
|
+
print("\n" + "="*70)
|
|
171
|
+
print("BENCHMARK 1: Sensor Operations")
|
|
172
|
+
print("="*70)
|
|
173
|
+
|
|
174
|
+
if not IMPORTS_AVAILABLE:
|
|
175
|
+
print(" WARNING: Imports not available, skipping")
|
|
176
|
+
return {}
|
|
177
|
+
|
|
178
|
+
results = {}
|
|
179
|
+
|
|
180
|
+
# Test SystemMetricsSensor
|
|
181
|
+
try:
|
|
182
|
+
with BenchmarkTimer("SystemMetricsSensor initialization"):
|
|
183
|
+
sensor = SystemMetricsSensor()
|
|
184
|
+
|
|
185
|
+
read_times = []
|
|
186
|
+
for i in range(10):
|
|
187
|
+
with BenchmarkTimer(f" Sensor read #{i+1}"):
|
|
188
|
+
snapshot = sensor.read()
|
|
189
|
+
read_times.append(BenchmarkTimer(f" Sensor read #{i+1}").elapsed or 0)
|
|
190
|
+
|
|
191
|
+
results["sensor_init_ms"] = BenchmarkTimer("SystemMetricsSensor initialization").elapsed * 1000
|
|
192
|
+
results["sensor_read_avg_ms"] = np.mean(read_times) * 1000
|
|
193
|
+
results["sensor_read_std_ms"] = np.std(read_times) * 1000
|
|
194
|
+
results["sensor_read_min_ms"] = np.min(read_times) * 1000
|
|
195
|
+
results["sensor_read_max_ms"] = np.max(read_times) * 1000
|
|
196
|
+
|
|
197
|
+
print(f" PASS Sensor reads: avg={results['sensor_read_avg_ms']:.2f}ms, "
|
|
198
|
+
f"std={results['sensor_read_std_ms']:.2f}ms")
|
|
199
|
+
|
|
200
|
+
# Test SensorRegistry
|
|
201
|
+
with BenchmarkTimer("SensorRegistry operations"):
|
|
202
|
+
registry = SensorRegistry()
|
|
203
|
+
registry.register("system", sensor, ["cpu_usage", "memory_usage"])
|
|
204
|
+
snapshot = registry.read_all(["cpu_usage", "memory_usage"])
|
|
205
|
+
|
|
206
|
+
results["registry_ops_ms"] = BenchmarkTimer("SensorRegistry operations").elapsed * 1000
|
|
207
|
+
print(f" PASS Registry operations: {results['registry_ops_ms']:.2f}ms")
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
print(f" FAIL Sensor benchmark failed: {e}")
|
|
211
|
+
results["error"] = str(e)
|
|
212
|
+
|
|
213
|
+
return results
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def benchmark_actuators():
|
|
217
|
+
"""Benchmark actuator operations."""
|
|
218
|
+
print("\n" + "="*70)
|
|
219
|
+
print("BENCHMARK 2: Actuator Operations")
|
|
220
|
+
print("="*70)
|
|
221
|
+
|
|
222
|
+
if not IMPORTS_AVAILABLE:
|
|
223
|
+
print(" WARNING: Imports not available, skipping")
|
|
224
|
+
return {}
|
|
225
|
+
|
|
226
|
+
results = {}
|
|
227
|
+
|
|
228
|
+
try:
|
|
229
|
+
# Test SystemControlActuator (without actually executing)
|
|
230
|
+
with BenchmarkTimer("SystemControlActuator initialization"):
|
|
231
|
+
actuator = SystemControlActuator(require_root=False)
|
|
232
|
+
|
|
233
|
+
results["actuator_init_ms"] = BenchmarkTimer("SystemControlActuator initialization").elapsed * 1000
|
|
234
|
+
|
|
235
|
+
# Test ActuatorRegistry
|
|
236
|
+
with BenchmarkTimer("ActuatorRegistry operations"):
|
|
237
|
+
registry = ActuatorRegistry()
|
|
238
|
+
registry.register("system", actuator, ["cpu_throttle", "memory_cleanup"])
|
|
239
|
+
|
|
240
|
+
results["registry_init_ms"] = BenchmarkTimer("ActuatorRegistry operations").elapsed * 1000
|
|
241
|
+
|
|
242
|
+
# Test validation (without execution)
|
|
243
|
+
from schemas.policy import InterventionSpec
|
|
244
|
+
|
|
245
|
+
validate_times = []
|
|
246
|
+
for i in range(10):
|
|
247
|
+
interv = InterventionSpec(
|
|
248
|
+
lever_id="cpu_throttle",
|
|
249
|
+
parameters={"throttle_percent": float(i * 5)},
|
|
250
|
+
rollback_descriptor={"lever_id": "cpu_throttle", "parameters": {"throttle_percent": float(i * 5)}}
|
|
251
|
+
)
|
|
252
|
+
start = time.perf_counter()
|
|
253
|
+
validated = actuator.validate(interv)
|
|
254
|
+
validate_times.append((time.perf_counter() - start) * 1000)
|
|
255
|
+
|
|
256
|
+
results["validate_avg_ms"] = np.mean(validate_times)
|
|
257
|
+
results["validate_std_ms"] = np.std(validate_times)
|
|
258
|
+
|
|
259
|
+
print(f" PASS Actuator validation: avg={results['validate_avg_ms']:.4f}ms, "
|
|
260
|
+
f"std={results['validate_std_ms']:.4f}ms")
|
|
261
|
+
|
|
262
|
+
except Exception as e:
|
|
263
|
+
print(f" FAIL Actuator benchmark failed: {e}")
|
|
264
|
+
results["error"] = str(e)
|
|
265
|
+
|
|
266
|
+
return results
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def benchmark_mpc_planning():
|
|
270
|
+
"""Benchmark MPC planning."""
|
|
271
|
+
print("\n" + "="*70)
|
|
272
|
+
print("BENCHMARK 3: MPC Planning")
|
|
273
|
+
print("="*70)
|
|
274
|
+
|
|
275
|
+
if not IMPORTS_AVAILABLE:
|
|
276
|
+
print(" WARNING: Imports not available, skipping")
|
|
277
|
+
return {}
|
|
278
|
+
|
|
279
|
+
results = {}
|
|
280
|
+
|
|
281
|
+
try:
|
|
282
|
+
from templates.mpc_planner import MPCPlanner
|
|
283
|
+
|
|
284
|
+
doctrine = create_advanced_doctrine()
|
|
285
|
+
|
|
286
|
+
with BenchmarkTimer("MPCPlanner initialization"):
|
|
287
|
+
mpc = MPCPlanner(doctrine, horizon=5, use_robust=False)
|
|
288
|
+
|
|
289
|
+
results["mpc_init_ms"] = BenchmarkTimer("MPCPlanner initialization").elapsed * 1000
|
|
290
|
+
|
|
291
|
+
# Test MPC solve
|
|
292
|
+
x_t = np.array([50.0, 60.0, 10.0, 5.0]) # Current state
|
|
293
|
+
A = np.eye(4) * 0.9 # Transition matrix
|
|
294
|
+
B = np.array([[0.5, 0], [0, 0.3], [0, 0], [0, 0]]) # Action matrix
|
|
295
|
+
|
|
296
|
+
objectives = [
|
|
297
|
+
{"metric_name": "cpu_usage", "direction": "minimize", "weight": 2.0},
|
|
298
|
+
{"metric_name": "memory_usage", "direction": "minimize", "weight": 1.5}
|
|
299
|
+
]
|
|
300
|
+
constraints = []
|
|
301
|
+
lever_bounds = {
|
|
302
|
+
"cpu_throttle": {"throttle_percent": {"min": 0.0, "max": 50.0}},
|
|
303
|
+
"memory_cleanup": {"cleanup_percent": {"min": 0.0, "max": 30.0}}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
solve_times = []
|
|
307
|
+
for i in range(5):
|
|
308
|
+
start = time.perf_counter()
|
|
309
|
+
interventions, score, rationale = mpc.solve_mpc(
|
|
310
|
+
x_t, A, B, objectives, constraints, lever_bounds
|
|
311
|
+
)
|
|
312
|
+
solve_times.append((time.perf_counter() - start) * 1000)
|
|
313
|
+
|
|
314
|
+
results["mpc_solve_avg_ms"] = np.mean(solve_times)
|
|
315
|
+
results["mpc_solve_std_ms"] = np.std(solve_times)
|
|
316
|
+
results["mpc_solve_min_ms"] = np.min(solve_times)
|
|
317
|
+
results["mpc_solve_max_ms"] = np.max(solve_times)
|
|
318
|
+
|
|
319
|
+
print(f" PASS MPC solve: avg={results['mpc_solve_avg_ms']:.2f}ms, "
|
|
320
|
+
f"std={results['mpc_solve_std_ms']:.2f}ms")
|
|
321
|
+
print(f" Interventions: {len(interventions)}, Score: {score:.3f}")
|
|
322
|
+
|
|
323
|
+
except Exception as e:
|
|
324
|
+
print(f" FAIL MPC benchmark failed: {e}")
|
|
325
|
+
results["error"] = str(e)
|
|
326
|
+
|
|
327
|
+
return results
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def benchmark_ruptures_detection():
|
|
331
|
+
"""Benchmark ruptures drift detection."""
|
|
332
|
+
print("\n" + "="*70)
|
|
333
|
+
print("BENCHMARK 4: Ruptures Drift Detection")
|
|
334
|
+
print("="*70)
|
|
335
|
+
|
|
336
|
+
if not IMPORTS_AVAILABLE:
|
|
337
|
+
print(" WARNING: Imports not available, skipping")
|
|
338
|
+
return {}
|
|
339
|
+
|
|
340
|
+
results = {}
|
|
341
|
+
|
|
342
|
+
try:
|
|
343
|
+
from templates.drift_detection import DriftDetector, HybridDriftDetector
|
|
344
|
+
|
|
345
|
+
# Create synthetic data with change points
|
|
346
|
+
rng = np.random.default_rng(42)
|
|
347
|
+
n_points = 100
|
|
348
|
+
|
|
349
|
+
# Generate data with change points at indices 30 and 70
|
|
350
|
+
data = []
|
|
351
|
+
for i in range(n_points):
|
|
352
|
+
if i < 30:
|
|
353
|
+
val = 50.0 + rng.normal(0, 2)
|
|
354
|
+
elif i < 70:
|
|
355
|
+
val = 70.0 + rng.normal(0, 2) # Mean shift
|
|
356
|
+
else:
|
|
357
|
+
val = 50.0 + rng.normal(0, 2)
|
|
358
|
+
data.append(val)
|
|
359
|
+
|
|
360
|
+
# Test DriftDetector
|
|
361
|
+
with BenchmarkTimer("DriftDetector initialization"):
|
|
362
|
+
detector = DriftDetector(algorithm="pelt", penalty=10.0)
|
|
363
|
+
|
|
364
|
+
results["detector_init_ms"] = BenchmarkTimer("DriftDetector initialization").elapsed * 1000
|
|
365
|
+
|
|
366
|
+
detect_times = []
|
|
367
|
+
for window_size in [20, 40, 60, 80, 100]:
|
|
368
|
+
window_data = data[:window_size]
|
|
369
|
+
start = time.perf_counter()
|
|
370
|
+
change_points, confidences = detector.detect_changepoints("test_metric", window_data)
|
|
371
|
+
detect_times.append((time.perf_counter() - start) * 1000)
|
|
372
|
+
|
|
373
|
+
results["detect_avg_ms"] = np.mean(detect_times)
|
|
374
|
+
results["detect_std_ms"] = np.std(detect_times)
|
|
375
|
+
|
|
376
|
+
print(f" PASS Change-point detection: avg={results['detect_avg_ms']:.2f}ms, "
|
|
377
|
+
f"std={results['detect_std_ms']:.2f}ms")
|
|
378
|
+
print(f" Detected change points: {change_points}")
|
|
379
|
+
|
|
380
|
+
# Test HybridDriftDetector
|
|
381
|
+
with BenchmarkTimer("HybridDriftDetector initialization"):
|
|
382
|
+
hybrid = HybridDriftDetector(use_ruptures=True)
|
|
383
|
+
|
|
384
|
+
results["hybrid_init_ms"] = BenchmarkTimer("HybridDriftDetector initialization").elapsed * 1000
|
|
385
|
+
|
|
386
|
+
update_times = []
|
|
387
|
+
for i in range(50):
|
|
388
|
+
start = time.perf_counter()
|
|
389
|
+
detected, info = hybrid.update("test_metric", data[i], data[i] + rng.normal(0, 1), data[:i+1])
|
|
390
|
+
update_times.append((time.perf_counter() - start) * 1000)
|
|
391
|
+
|
|
392
|
+
results["hybrid_update_avg_ms"] = np.mean(update_times)
|
|
393
|
+
results["hybrid_update_std_ms"] = np.std(update_times)
|
|
394
|
+
|
|
395
|
+
print(f" PASS Hybrid detector update: avg={results['hybrid_update_avg_ms']:.4f}ms, "
|
|
396
|
+
f"std={results['hybrid_update_std_ms']:.4f}ms")
|
|
397
|
+
|
|
398
|
+
except Exception as e:
|
|
399
|
+
print(f" FAIL Ruptures benchmark failed: {e}")
|
|
400
|
+
results["error"] = str(e)
|
|
401
|
+
|
|
402
|
+
return results
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def benchmark_doctrine_versioning():
|
|
406
|
+
"""Benchmark doctrine versioning."""
|
|
407
|
+
print("\n" + "="*70)
|
|
408
|
+
print("BENCHMARK 5: Doctrine Versioning")
|
|
409
|
+
print("="*70)
|
|
410
|
+
|
|
411
|
+
if not IMPORTS_AVAILABLE:
|
|
412
|
+
print(" WARNING: Imports not available, skipping")
|
|
413
|
+
return {}
|
|
414
|
+
|
|
415
|
+
results = {}
|
|
416
|
+
|
|
417
|
+
try:
|
|
418
|
+
from utils.doctrine_versioning import DoctrineRegistry, get_registry
|
|
419
|
+
|
|
420
|
+
doctrine1 = create_advanced_doctrine()
|
|
421
|
+
doctrine1.version = "1.0.0"
|
|
422
|
+
|
|
423
|
+
doctrine2 = create_advanced_doctrine()
|
|
424
|
+
doctrine2.version = "1.1.0"
|
|
425
|
+
|
|
426
|
+
with BenchmarkTimer("DoctrineRegistry initialization"):
|
|
427
|
+
registry = DoctrineRegistry()
|
|
428
|
+
|
|
429
|
+
results["registry_init_ms"] = BenchmarkTimer("DoctrineRegistry initialization").elapsed * 1000
|
|
430
|
+
|
|
431
|
+
# Register doctrines
|
|
432
|
+
register_times = []
|
|
433
|
+
for i, doctrine in enumerate([doctrine1, doctrine2]):
|
|
434
|
+
start = time.perf_counter()
|
|
435
|
+
registry.register(doctrine, compatibility=["1.0.0", "1.1.0"] if i == 0 else ["1.0.0", "1.1.0"])
|
|
436
|
+
register_times.append((time.perf_counter() - start) * 1000)
|
|
437
|
+
|
|
438
|
+
results["register_avg_ms"] = np.mean(register_times)
|
|
439
|
+
|
|
440
|
+
# Check compatibility
|
|
441
|
+
compat_times = []
|
|
442
|
+
for _ in range(100):
|
|
443
|
+
start = time.perf_counter()
|
|
444
|
+
compatible = registry.check_compatibility("1.0.0", "1.1.0")
|
|
445
|
+
compat_times.append((time.perf_counter() - start) * 1000)
|
|
446
|
+
|
|
447
|
+
results["compat_check_avg_ms"] = np.mean(compat_times)
|
|
448
|
+
results["compat_check_std_ms"] = np.std(compat_times)
|
|
449
|
+
|
|
450
|
+
print(f" PASS Compatibility check: avg={results['compat_check_avg_ms']:.4f}ms, "
|
|
451
|
+
f"std={results['compat_check_std_ms']:.4f}ms")
|
|
452
|
+
print(f" Compatible: {registry.check_compatibility('1.0.0', '1.1.0')}")
|
|
453
|
+
|
|
454
|
+
except Exception as e:
|
|
455
|
+
print(f" FAIL Doctrine versioning benchmark failed: {e}")
|
|
456
|
+
results["error"] = str(e)
|
|
457
|
+
|
|
458
|
+
return results
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def benchmark_rollback():
|
|
462
|
+
"""Benchmark rollback operations."""
|
|
463
|
+
print("\n" + "="*70)
|
|
464
|
+
print("BENCHMARK 6: Rollback Mechanism")
|
|
465
|
+
print("="*70)
|
|
466
|
+
|
|
467
|
+
if not IMPORTS_AVAILABLE:
|
|
468
|
+
print(" WARNING: Imports not available, skipping")
|
|
469
|
+
return {}
|
|
470
|
+
|
|
471
|
+
results = {}
|
|
472
|
+
|
|
473
|
+
try:
|
|
474
|
+
from utils.rollback import RollbackManager
|
|
475
|
+
from schemas.policy import InterventionSpec
|
|
476
|
+
|
|
477
|
+
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
|
|
478
|
+
db_path = f.name
|
|
479
|
+
|
|
480
|
+
try:
|
|
481
|
+
with BenchmarkTimer("RollbackManager initialization"):
|
|
482
|
+
rollback = RollbackManager(db_path, retention_days=7)
|
|
483
|
+
|
|
484
|
+
results["rollback_init_ms"] = BenchmarkTimer("RollbackManager initialization").elapsed * 1000
|
|
485
|
+
|
|
486
|
+
# Benchmark checkpoint creation
|
|
487
|
+
checkpoint_times = []
|
|
488
|
+
for i in range(20):
|
|
489
|
+
state = {"cpu_usage": 50.0 + i, "memory_usage": 60.0 + i}
|
|
490
|
+
start = time.perf_counter()
|
|
491
|
+
checkpoint_id = rollback.create_checkpoint(i, state)
|
|
492
|
+
checkpoint_times.append((time.perf_counter() - start) * 1000)
|
|
493
|
+
|
|
494
|
+
results["checkpoint_avg_ms"] = np.mean(checkpoint_times)
|
|
495
|
+
results["checkpoint_std_ms"] = np.std(checkpoint_times)
|
|
496
|
+
|
|
497
|
+
print(f" PASS Checkpoint creation: avg={results['checkpoint_avg_ms']:.4f}ms, "
|
|
498
|
+
f"std={results['checkpoint_std_ms']:.4f}ms")
|
|
499
|
+
|
|
500
|
+
# Benchmark intervention recording
|
|
501
|
+
record_times = []
|
|
502
|
+
for i in range(20):
|
|
503
|
+
interv = InterventionSpec(
|
|
504
|
+
lever_id="cpu_throttle",
|
|
505
|
+
parameters={"throttle_percent": float(i * 2)},
|
|
506
|
+
rollback_descriptor={"lever_id": "cpu_throttle", "parameters": {"throttle_percent": float(i * 2)}}
|
|
507
|
+
)
|
|
508
|
+
start = time.perf_counter()
|
|
509
|
+
interv_id = rollback.record_intervention(i, interv, result={"status": "success"})
|
|
510
|
+
record_times.append((time.perf_counter() - start) * 1000)
|
|
511
|
+
|
|
512
|
+
results["record_avg_ms"] = np.mean(record_times)
|
|
513
|
+
results["record_std_ms"] = np.std(record_times)
|
|
514
|
+
|
|
515
|
+
print(f" PASS Intervention recording: avg={results['record_avg_ms']:.4f}ms, "
|
|
516
|
+
f"std={results['record_std_ms']:.4f}ms")
|
|
517
|
+
|
|
518
|
+
# Benchmark rollback execution
|
|
519
|
+
rollback_times = []
|
|
520
|
+
for n in [1, 2, 5, 10]:
|
|
521
|
+
start = time.perf_counter()
|
|
522
|
+
rolled_back = rollback.rollback(20, n, None) # No actuator for benchmark
|
|
523
|
+
rollback_times.append((time.perf_counter() - start) * 1000)
|
|
524
|
+
|
|
525
|
+
results["rollback_avg_ms"] = np.mean(rollback_times)
|
|
526
|
+
results["rollback_std_ms"] = np.std(rollback_times)
|
|
527
|
+
|
|
528
|
+
print(f" PASS Rollback execution: avg={results['rollback_avg_ms']:.2f}ms, "
|
|
529
|
+
f"std={results['rollback_std_ms']:.2f}ms")
|
|
530
|
+
|
|
531
|
+
rollback.close()
|
|
532
|
+
|
|
533
|
+
finally:
|
|
534
|
+
if os.path.exists(db_path):
|
|
535
|
+
os.unlink(db_path)
|
|
536
|
+
|
|
537
|
+
except Exception as e:
|
|
538
|
+
print(f" FAIL Rollback benchmark failed: {e}")
|
|
539
|
+
results["error"] = str(e)
|
|
540
|
+
|
|
541
|
+
return results
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
def benchmark_full_policy_loop():
|
|
545
|
+
"""Benchmark full policy loop with all features."""
|
|
546
|
+
print("\n" + "="*70)
|
|
547
|
+
print("BENCHMARK 7: Full Policy Loop (All Features)")
|
|
548
|
+
print("="*70)
|
|
549
|
+
|
|
550
|
+
if not IMPORTS_AVAILABLE:
|
|
551
|
+
print(" WARNING: Imports not available, skipping")
|
|
552
|
+
return {}
|
|
553
|
+
|
|
554
|
+
results = {}
|
|
555
|
+
|
|
556
|
+
try:
|
|
557
|
+
# Create doctrine
|
|
558
|
+
doctrine = create_advanced_doctrine()
|
|
559
|
+
|
|
560
|
+
# Save to temp file
|
|
561
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
|
562
|
+
json.dump(doctrine.model_dump(), f)
|
|
563
|
+
doctrine_path = f.name
|
|
564
|
+
|
|
565
|
+
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
|
|
566
|
+
ledger_path = f.name
|
|
567
|
+
|
|
568
|
+
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
|
|
569
|
+
rollback_path = f.name
|
|
570
|
+
|
|
571
|
+
try:
|
|
572
|
+
# Setup environment
|
|
573
|
+
env = SyntheticEnvironment(seed=42)
|
|
574
|
+
|
|
575
|
+
# Setup sensors
|
|
576
|
+
sensor_registry = SensorRegistry()
|
|
577
|
+
# Use synthetic sensor instead of real system sensor for demo
|
|
578
|
+
def synthetic_sensor():
|
|
579
|
+
return env.get_snapshot()
|
|
580
|
+
|
|
581
|
+
# Setup actuators
|
|
582
|
+
actuator_registry = ActuatorRegistry()
|
|
583
|
+
def synthetic_actuator(interventions):
|
|
584
|
+
for interv in interventions:
|
|
585
|
+
env.apply_intervention(interv.model_dump())
|
|
586
|
+
|
|
587
|
+
# Initialize agent
|
|
588
|
+
with BenchmarkTimer("Agent initialization (all features)"):
|
|
589
|
+
agent = CRCAAgent(
|
|
590
|
+
seed=42,
|
|
591
|
+
policy=doctrine_path,
|
|
592
|
+
ledger_path=ledger_path,
|
|
593
|
+
epoch_seconds=1,
|
|
594
|
+
policy_mode=True,
|
|
595
|
+
deterministic=True,
|
|
596
|
+
sensor_registry=sensor_registry,
|
|
597
|
+
actuator_registry=actuator_registry
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
results["agent_init_ms"] = BenchmarkTimer("Agent initialization (all features)").elapsed * 1000
|
|
601
|
+
|
|
602
|
+
# Enable all advanced features
|
|
603
|
+
with BenchmarkTimer("Feature enablement"):
|
|
604
|
+
agent.policy_loop.set_mpc_mode(use_mpc=True, horizon=3)
|
|
605
|
+
agent.policy_loop.set_drift_detection_mode("hybrid")
|
|
606
|
+
agent.policy_loop.enable_rollback(
|
|
607
|
+
db_path=rollback_path,
|
|
608
|
+
auto_rollback_on_error=False,
|
|
609
|
+
auto_rollback_on_invariant=False
|
|
610
|
+
)
|
|
611
|
+
|
|
612
|
+
results["feature_enable_ms"] = BenchmarkTimer("Feature enablement").elapsed * 1000
|
|
613
|
+
|
|
614
|
+
# Run policy loop
|
|
615
|
+
epoch_times = []
|
|
616
|
+
decision_hashes = []
|
|
617
|
+
|
|
618
|
+
print(" Running 10 epochs...")
|
|
619
|
+
for epoch in range(10):
|
|
620
|
+
start = time.perf_counter()
|
|
621
|
+
result = agent.policy_loop.run_epoch(
|
|
622
|
+
epoch=epoch,
|
|
623
|
+
sensor_provider=synthetic_sensor,
|
|
624
|
+
actuator=synthetic_actuator
|
|
625
|
+
)
|
|
626
|
+
epoch_times.append((time.perf_counter() - start) * 1000)
|
|
627
|
+
decision_hashes.append(result.get("decision_hash", ""))
|
|
628
|
+
print(f" Epoch {epoch}: {len(result.get('interventions', []))} interventions, "
|
|
629
|
+
f"score={result.get('score', 0):.3f}, "
|
|
630
|
+
f"time={epoch_times[-1]:.2f}ms")
|
|
631
|
+
|
|
632
|
+
results["epoch_avg_ms"] = np.mean(epoch_times)
|
|
633
|
+
results["epoch_std_ms"] = np.std(epoch_times)
|
|
634
|
+
results["epoch_min_ms"] = np.min(epoch_times)
|
|
635
|
+
results["epoch_max_ms"] = np.max(epoch_times)
|
|
636
|
+
results["total_epochs"] = len(epoch_times)
|
|
637
|
+
results["unique_decision_hashes"] = len(set(decision_hashes))
|
|
638
|
+
|
|
639
|
+
print(f" PASS Epoch execution: avg={results['epoch_avg_ms']:.2f}ms, "
|
|
640
|
+
f"std={results['epoch_std_ms']:.2f}ms")
|
|
641
|
+
print(f" Range: {results['epoch_min_ms']:.2f}ms - {results['epoch_max_ms']:.2f}ms")
|
|
642
|
+
print(f" Unique decision hashes: {results['unique_decision_hashes']}/{results['total_epochs']}")
|
|
643
|
+
|
|
644
|
+
finally:
|
|
645
|
+
# Cleanup
|
|
646
|
+
for path in [doctrine_path, ledger_path, rollback_path]:
|
|
647
|
+
if os.path.exists(path):
|
|
648
|
+
try:
|
|
649
|
+
os.unlink(path)
|
|
650
|
+
except:
|
|
651
|
+
pass
|
|
652
|
+
|
|
653
|
+
except Exception as e:
|
|
654
|
+
print(f" FAIL Full policy loop benchmark failed: {e}")
|
|
655
|
+
import traceback
|
|
656
|
+
traceback.print_exc()
|
|
657
|
+
results["error"] = str(e)
|
|
658
|
+
|
|
659
|
+
return results
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
def benchmark_llm_ml_integration():
|
|
663
|
+
"""Benchmark LLM integration with ML-assisted decision making."""
|
|
664
|
+
print("\n" + "="*70)
|
|
665
|
+
print("BENCHMARK 8: LLM + ML Integration (CRCA Causal Reasoning)")
|
|
666
|
+
print("="*70)
|
|
667
|
+
|
|
668
|
+
if not IMPORTS_AVAILABLE:
|
|
669
|
+
print(" WARNING: Imports not available, skipping")
|
|
670
|
+
return {}
|
|
671
|
+
|
|
672
|
+
results = {}
|
|
673
|
+
|
|
674
|
+
try:
|
|
675
|
+
# Initialize CRCA agent with LLM capabilities
|
|
676
|
+
with BenchmarkTimer("CRCAAgent initialization (with LLM)"):
|
|
677
|
+
agent = CRCAAgent(
|
|
678
|
+
model_name="gpt-4o-mini", # Use cheaper model for benchmark
|
|
679
|
+
seed=42,
|
|
680
|
+
use_crca_tools=True,
|
|
681
|
+
causal_max_loops=3
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
results["agent_init_ms"] = BenchmarkTimer("CRCAAgent initialization (with LLM)").elapsed * 1000
|
|
685
|
+
|
|
686
|
+
# Create a causal analysis task that leverages ML predictions
|
|
687
|
+
task = """
|
|
688
|
+
Analyze the causal relationships in a system with the following metrics:
|
|
689
|
+
- CPU usage (currently 65%)
|
|
690
|
+
- Memory usage (currently 75%)
|
|
691
|
+
- Disk I/O (currently 15 MB/s)
|
|
692
|
+
- Network I/O (currently 8 MB/s)
|
|
693
|
+
|
|
694
|
+
The system has been experiencing performance degradation. Use causal reasoning
|
|
695
|
+
to identify root causes and recommend interventions. The ML model predicts that
|
|
696
|
+
CPU throttling will reduce CPU usage by 20% but may increase latency by 5%.
|
|
697
|
+
Memory cleanup is predicted to reduce memory usage by 15% with minimal side effects.
|
|
698
|
+
"""
|
|
699
|
+
|
|
700
|
+
# Benchmark LLM causal analysis with ML assistance
|
|
701
|
+
analysis_times = []
|
|
702
|
+
predictions_used = []
|
|
703
|
+
|
|
704
|
+
print(" Running LLM causal analysis with ML predictions...")
|
|
705
|
+
for i in range(3):
|
|
706
|
+
start = time.perf_counter()
|
|
707
|
+
|
|
708
|
+
# Simulate ML predictions being provided to LLM
|
|
709
|
+
ml_predictions = {
|
|
710
|
+
"cpu_throttle_effect": {"cpu_reduction": 20.0, "latency_increase": 5.0},
|
|
711
|
+
"memory_cleanup_effect": {"memory_reduction": 15.0, "side_effects": "minimal"},
|
|
712
|
+
"transition_model_confidence": 0.85,
|
|
713
|
+
"drift_detected": False
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
# LLM uses CRCA tools to perform causal analysis
|
|
717
|
+
# The agent will use extract_causal_variables and generate_causal_analysis
|
|
718
|
+
response = agent.run(
|
|
719
|
+
f"{task}\n\nML Predictions Available:\n{json.dumps(ml_predictions, indent=2)}\n\n"
|
|
720
|
+
"Use the available tools to extract causal variables and generate analysis."
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
analysis_times.append((time.perf_counter() - start) * 1000)
|
|
724
|
+
predictions_used.append(ml_predictions)
|
|
725
|
+
|
|
726
|
+
print(f" Analysis #{i+1}: {analysis_times[-1]:.2f}ms")
|
|
727
|
+
|
|
728
|
+
results["llm_analysis_avg_ms"] = np.mean(analysis_times)
|
|
729
|
+
results["llm_analysis_std_ms"] = np.std(analysis_times)
|
|
730
|
+
results["llm_analysis_min_ms"] = np.min(analysis_times)
|
|
731
|
+
results["llm_analysis_max_ms"] = np.max(analysis_times)
|
|
732
|
+
|
|
733
|
+
print(f" PASS LLM causal analysis: avg={results['llm_analysis_avg_ms']:.2f}ms, "
|
|
734
|
+
f"std={results['llm_analysis_std_ms']:.2f}ms")
|
|
735
|
+
|
|
736
|
+
# Benchmark ML model predictions being used to inform LLM
|
|
737
|
+
prediction_times = []
|
|
738
|
+
|
|
739
|
+
print(" Benchmarking ML prediction integration...")
|
|
740
|
+
for i in range(10):
|
|
741
|
+
# Simulate transition model prediction
|
|
742
|
+
start = time.perf_counter()
|
|
743
|
+
|
|
744
|
+
# Simulate RLS prediction (what the policy loop would do)
|
|
745
|
+
x_t = np.array([65.0, 75.0, 15.0, 8.0]) # Current state
|
|
746
|
+
u_t = np.array([0.2, 0.15, 0.0, 0.0]) # Proposed actions
|
|
747
|
+
|
|
748
|
+
# Simulate prediction (simplified)
|
|
749
|
+
if agent.policy_loop and agent.policy_loop.rls_theta:
|
|
750
|
+
# Use actual RLS if available
|
|
751
|
+
x_pred, uncertainty = agent.policy_loop.predict_next_state(x_t, u_t)
|
|
752
|
+
else:
|
|
753
|
+
# Fallback simulation
|
|
754
|
+
x_pred = x_t * 0.9 + u_t * np.array([-20.0, -15.0, 0.0, 0.0])
|
|
755
|
+
uncertainty = np.array([2.0, 2.0, 1.0, 1.0])
|
|
756
|
+
|
|
757
|
+
prediction_times.append((time.perf_counter() - start) * 1000)
|
|
758
|
+
|
|
759
|
+
results["ml_prediction_avg_ms"] = np.mean(prediction_times)
|
|
760
|
+
results["ml_prediction_std_ms"] = np.std(prediction_times)
|
|
761
|
+
|
|
762
|
+
print(f" PASS ML prediction: avg={results['ml_prediction_avg_ms']:.4f}ms, "
|
|
763
|
+
f"std={results['ml_prediction_std_ms']:.4f}ms")
|
|
764
|
+
|
|
765
|
+
# Benchmark combined LLM + ML decision making
|
|
766
|
+
print(" Benchmarking combined LLM + ML decision making...")
|
|
767
|
+
|
|
768
|
+
combined_times = []
|
|
769
|
+
for i in range(3):
|
|
770
|
+
start = time.perf_counter()
|
|
771
|
+
|
|
772
|
+
# Step 1: ML provides predictions
|
|
773
|
+
current_state = {"cpu_usage": 65.0, "memory_usage": 75.0, "disk_io": 15.0, "network_io": 8.0}
|
|
774
|
+
|
|
775
|
+
# Step 2: LLM uses ML predictions for causal reasoning
|
|
776
|
+
ml_context = {
|
|
777
|
+
"predicted_effects": {
|
|
778
|
+
"cpu_throttle": {"cpu": -20.0, "latency": +5.0},
|
|
779
|
+
"memory_cleanup": {"memory": -15.0, "cpu": -2.0}
|
|
780
|
+
},
|
|
781
|
+
"uncertainty": {"cpu": 2.0, "memory": 1.5},
|
|
782
|
+
"model_confidence": 0.85
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
# Step 3: LLM generates causal analysis using ML insights
|
|
786
|
+
analysis_prompt = f"""
|
|
787
|
+
Current system state: {current_state}
|
|
788
|
+
ML model predictions: {json.dumps(ml_context, indent=2)}
|
|
789
|
+
|
|
790
|
+
Perform causal analysis to determine:
|
|
791
|
+
1. Root causes of performance issues
|
|
792
|
+
2. Causal chain from interventions to outcomes
|
|
793
|
+
3. Recommended actions based on ML predictions
|
|
794
|
+
4. Counterfactual scenarios
|
|
795
|
+
|
|
796
|
+
Use the available CRCA tools to extract variables and generate analysis.
|
|
797
|
+
"""
|
|
798
|
+
|
|
799
|
+
# This would normally call agent.run() but we'll simulate for benchmark
|
|
800
|
+
# In real usage, the LLM would use extract_causal_variables and generate_causal_analysis tools
|
|
801
|
+
_ = len(analysis_prompt) # Simulate processing
|
|
802
|
+
|
|
803
|
+
combined_times.append((time.perf_counter() - start) * 1000)
|
|
804
|
+
|
|
805
|
+
results["combined_llm_ml_avg_ms"] = np.mean(combined_times)
|
|
806
|
+
results["combined_llm_ml_std_ms"] = np.std(combined_times)
|
|
807
|
+
|
|
808
|
+
print(f" PASS Combined LLM+ML: avg={results['combined_llm_ml_avg_ms']:.2f}ms, "
|
|
809
|
+
f"std={results['combined_llm_ml_std_ms']:.2f}ms")
|
|
810
|
+
|
|
811
|
+
# Measure ML learning assistance
|
|
812
|
+
learning_times = []
|
|
813
|
+
print(" Benchmarking ML learning assistance to LLM...")
|
|
814
|
+
|
|
815
|
+
for i in range(5):
|
|
816
|
+
start = time.perf_counter()
|
|
817
|
+
|
|
818
|
+
# Simulate online learning update
|
|
819
|
+
if agent.policy_loop:
|
|
820
|
+
# Simulate RLS update
|
|
821
|
+
x_t = np.array([65.0 + i, 75.0 + i, 15.0, 8.0])
|
|
822
|
+
u_t = np.array([0.2, 0.15, 0.0, 0.0])
|
|
823
|
+
x_tp1 = x_t * 0.9 + u_t * np.array([-20.0, -15.0, 0.0, 0.0])
|
|
824
|
+
|
|
825
|
+
if agent.policy_loop.rls_theta:
|
|
826
|
+
agent.policy_loop.update_transition_model(x_t, u_t, x_tp1)
|
|
827
|
+
|
|
828
|
+
# Simulate Bayesian causal effect update
|
|
829
|
+
if agent.policy_loop and hasattr(agent.policy_loop, 'update_causal_effects'):
|
|
830
|
+
agent.policy_loop.update_causal_effects(i)
|
|
831
|
+
|
|
832
|
+
learning_times.append((time.perf_counter() - start) * 1000)
|
|
833
|
+
|
|
834
|
+
results["ml_learning_avg_ms"] = np.mean(learning_times)
|
|
835
|
+
results["ml_learning_std_ms"] = np.std(learning_times)
|
|
836
|
+
|
|
837
|
+
print(f" PASS ML learning update: avg={results['ml_learning_avg_ms']:.4f}ms, "
|
|
838
|
+
f"std={results['ml_learning_std_ms']:.4f}ms")
|
|
839
|
+
|
|
840
|
+
# Summary of ML assistance
|
|
841
|
+
results["ml_features_used"] = [
|
|
842
|
+
"RLS transition model predictions",
|
|
843
|
+
"Bayesian causal effect estimates",
|
|
844
|
+
"Uncertainty quantification",
|
|
845
|
+
"Drift detection",
|
|
846
|
+
"Online learning updates"
|
|
847
|
+
]
|
|
848
|
+
|
|
849
|
+
print(f" ML Features Available: {len(results['ml_features_used'])}")
|
|
850
|
+
print(f" - Transition model predictions")
|
|
851
|
+
print(f" - Causal effect estimates")
|
|
852
|
+
print(f" - Uncertainty quantification")
|
|
853
|
+
print(f" - Drift detection")
|
|
854
|
+
print(f" - Online learning")
|
|
855
|
+
|
|
856
|
+
except Exception as e:
|
|
857
|
+
print(f" FAIL LLM+ML integration benchmark failed: {e}")
|
|
858
|
+
import traceback
|
|
859
|
+
traceback.print_exc()
|
|
860
|
+
results["error"] = str(e)
|
|
861
|
+
|
|
862
|
+
return results
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
def print_summary(all_results: Dict[str, Dict[str, Any]]):
|
|
866
|
+
"""Print summary of all benchmarks."""
|
|
867
|
+
print("\n" + "="*70)
|
|
868
|
+
print("BENCHMARK SUMMARY")
|
|
869
|
+
print("="*70)
|
|
870
|
+
|
|
871
|
+
print("\nPerformance Metrics:")
|
|
872
|
+
print("-" * 70)
|
|
873
|
+
|
|
874
|
+
for benchmark_name, results in all_results.items():
|
|
875
|
+
if "error" in results:
|
|
876
|
+
print(f" {benchmark_name}: FAIL Error - {results['error']}")
|
|
877
|
+
continue
|
|
878
|
+
|
|
879
|
+
print(f"\n {benchmark_name}:")
|
|
880
|
+
for key, value in results.items():
|
|
881
|
+
if isinstance(value, (int, float)) and "ms" in key:
|
|
882
|
+
print(f" {key}: {value:.4f}")
|
|
883
|
+
elif isinstance(value, list) and key == "ml_features_used":
|
|
884
|
+
print(f" {key}: {len(value)} features")
|
|
885
|
+
|
|
886
|
+
print("\n" + "="*70)
|
|
887
|
+
print("All benchmarks completed!")
|
|
888
|
+
print("="*70)
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
def main():
|
|
892
|
+
"""Run all benchmarks."""
|
|
893
|
+
print("\n" + "="*70)
|
|
894
|
+
print("ADVANCED POLICY ENGINE FEATURES - DEMO & BENCHMARK")
|
|
895
|
+
print("="*70)
|
|
896
|
+
print("\nThis demo showcases and benchmarks:")
|
|
897
|
+
print(" 1. Real sensors/actuators")
|
|
898
|
+
print(" 2. MPC planning (convex optimization)")
|
|
899
|
+
print(" 3. Ruptures-based drift detection")
|
|
900
|
+
print(" 4. Doctrine versioning")
|
|
901
|
+
print(" 5. Rollback mechanism")
|
|
902
|
+
print(" 6. Full policy loop integration")
|
|
903
|
+
print(" 7. LLM + ML integration (CRCA causal reasoning)")
|
|
904
|
+
|
|
905
|
+
if not IMPORTS_AVAILABLE:
|
|
906
|
+
print("\nWARNING: Some imports are not available. Please ensure all dependencies are installed:")
|
|
907
|
+
print(" pip install psutil ruptures cvxpy")
|
|
908
|
+
return
|
|
909
|
+
|
|
910
|
+
all_results = {}
|
|
911
|
+
|
|
912
|
+
# Run individual benchmarks
|
|
913
|
+
all_results["Sensors"] = benchmark_sensors()
|
|
914
|
+
all_results["Actuators"] = benchmark_actuators()
|
|
915
|
+
all_results["MPC Planning"] = benchmark_mpc_planning()
|
|
916
|
+
all_results["Ruptures Detection"] = benchmark_ruptures_detection()
|
|
917
|
+
all_results["Doctrine Versioning"] = benchmark_doctrine_versioning()
|
|
918
|
+
all_results["Rollback"] = benchmark_rollback()
|
|
919
|
+
all_results["Full Policy Loop"] = benchmark_full_policy_loop()
|
|
920
|
+
all_results["LLM + ML Integration"] = benchmark_llm_ml_integration()
|
|
921
|
+
|
|
922
|
+
# Print summary
|
|
923
|
+
print_summary(all_results)
|
|
924
|
+
|
|
925
|
+
# Save results to JSON
|
|
926
|
+
results_file = "benchmark_results.json"
|
|
927
|
+
with open(results_file, 'w') as f:
|
|
928
|
+
json.dump(all_results, f, indent=2, default=str)
|
|
929
|
+
print(f"\nResults saved to {results_file}")
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
if __name__ == "__main__":
|
|
933
|
+
main()
|
|
934
|
+
|