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
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""Drift detection using ruptures library for change-point detection.
|
|
2
|
+
|
|
3
|
+
Provides advanced change-point detection beyond simple CUSUM,
|
|
4
|
+
supporting multiple change points and per-metric detection.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
8
|
+
import numpy as np
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
# Try to import ruptures
|
|
12
|
+
try:
|
|
13
|
+
import ruptures as rpt
|
|
14
|
+
RUPTURES_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
RUPTURES_AVAILABLE = False
|
|
17
|
+
logger.warning("ruptures not available - drift detection will use CUSUM only")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DriftDetector:
|
|
21
|
+
"""Change-point detection using ruptures library.
|
|
22
|
+
|
|
23
|
+
Supports multiple change-point detection algorithms:
|
|
24
|
+
- Pelt: Optimal segmentation (penalized likelihood)
|
|
25
|
+
- Dynp: Dynamic programming (exact solution)
|
|
26
|
+
- Binseg: Binary segmentation (fast approximation)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
algorithm: str = "pelt",
|
|
32
|
+
min_size: int = 2,
|
|
33
|
+
penalty: float = 10.0,
|
|
34
|
+
model: str = "rbf"
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Initialize drift detector.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
algorithm: Detection algorithm ("pelt", "dynp", "binseg")
|
|
41
|
+
min_size: Minimum segment size
|
|
42
|
+
penalty: Penalty parameter for Pelt
|
|
43
|
+
model: Change-point model ("rbf", "l2", "l1", "normal", "ar")
|
|
44
|
+
"""
|
|
45
|
+
self.algorithm = algorithm
|
|
46
|
+
self.min_size = min_size
|
|
47
|
+
self.penalty = penalty
|
|
48
|
+
self.model = model
|
|
49
|
+
self.detectors: Dict[str, Any] = {} # Per-metric detectors
|
|
50
|
+
self.change_points: Dict[str, List[int]] = {} # Per-metric change points
|
|
51
|
+
self.confidence_scores: Dict[str, List[float]] = {} # Per-metric confidence
|
|
52
|
+
|
|
53
|
+
def detect_changepoints(
|
|
54
|
+
self,
|
|
55
|
+
metric_name: str,
|
|
56
|
+
metric_history: List[float],
|
|
57
|
+
min_history: int = 10
|
|
58
|
+
) -> Tuple[List[int], List[float]]:
|
|
59
|
+
"""
|
|
60
|
+
Detect change points in metric history.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
metric_name: Name of the metric
|
|
64
|
+
metric_history: Historical values of the metric
|
|
65
|
+
min_history: Minimum history length required
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Tuple of (change_point_indices, confidence_scores)
|
|
69
|
+
"""
|
|
70
|
+
if not RUPTURES_AVAILABLE:
|
|
71
|
+
return [], []
|
|
72
|
+
|
|
73
|
+
if len(metric_history) < min_history:
|
|
74
|
+
return [], []
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
# Convert to numpy array
|
|
78
|
+
signal = np.array(metric_history).reshape(-1, 1)
|
|
79
|
+
|
|
80
|
+
# Initialize detector if needed
|
|
81
|
+
if metric_name not in self.detectors:
|
|
82
|
+
if self.algorithm == "pelt":
|
|
83
|
+
self.detectors[metric_name] = rpt.Pelt(model=self.model, min_size=self.min_size).fit(signal)
|
|
84
|
+
elif self.algorithm == "dynp":
|
|
85
|
+
self.detectors[metric_name] = rpt.Dynp(model=self.model, min_size=self.min_size).fit(signal)
|
|
86
|
+
elif self.algorithm == "binseg":
|
|
87
|
+
self.detectors[metric_name] = rpt.Binseg(model=self.model, min_size=self.min_size).fit(signal)
|
|
88
|
+
else:
|
|
89
|
+
logger.warning(f"Unknown algorithm {self.algorithm}, using Pelt")
|
|
90
|
+
self.detectors[metric_name] = rpt.Pelt(model=self.model, min_size=self.min_size).fit(signal)
|
|
91
|
+
else:
|
|
92
|
+
# Update detector with new data
|
|
93
|
+
self.detectors[metric_name].fit(signal)
|
|
94
|
+
|
|
95
|
+
# Detect change points
|
|
96
|
+
detector = self.detectors[metric_name]
|
|
97
|
+
|
|
98
|
+
if self.algorithm == "pelt":
|
|
99
|
+
change_points = detector.predict(pen=self.penalty)
|
|
100
|
+
elif self.algorithm == "dynp":
|
|
101
|
+
# For Dynp, need to specify number of change points
|
|
102
|
+
# Use penalty to estimate number
|
|
103
|
+
n_bkps = max(1, int(len(signal) / (self.penalty * 10)))
|
|
104
|
+
change_points = detector.predict(n_bkps=n_bkps)
|
|
105
|
+
elif self.algorithm == "binseg":
|
|
106
|
+
n_bkps = max(1, int(len(signal) / (self.penalty * 10)))
|
|
107
|
+
change_points = detector.predict(n_bkps=n_bkps)
|
|
108
|
+
else:
|
|
109
|
+
change_points = []
|
|
110
|
+
|
|
111
|
+
# Remove last point (end of signal) if present
|
|
112
|
+
if change_points and change_points[-1] == len(signal):
|
|
113
|
+
change_points = change_points[:-1]
|
|
114
|
+
|
|
115
|
+
# Compute confidence scores (simplified: based on segment variance differences)
|
|
116
|
+
confidence_scores = []
|
|
117
|
+
for cp in change_points:
|
|
118
|
+
if cp > 0 and cp < len(signal):
|
|
119
|
+
# Compare variance before and after change point
|
|
120
|
+
before = signal[:cp]
|
|
121
|
+
after = signal[cp:]
|
|
122
|
+
var_before = np.var(before) if len(before) > 1 else 0.0
|
|
123
|
+
var_after = np.var(after) if len(after) > 1 else 0.0
|
|
124
|
+
# Confidence based on variance difference
|
|
125
|
+
confidence = min(1.0, abs(var_after - var_before) / (np.var(signal) + 1e-6))
|
|
126
|
+
confidence_scores.append(confidence)
|
|
127
|
+
else:
|
|
128
|
+
confidence_scores.append(0.0)
|
|
129
|
+
|
|
130
|
+
# Store results
|
|
131
|
+
self.change_points[metric_name] = change_points
|
|
132
|
+
self.confidence_scores[metric_name] = confidence_scores
|
|
133
|
+
|
|
134
|
+
return change_points, confidence_scores
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(f"Change-point detection failed for {metric_name}: {e}")
|
|
138
|
+
return [], []
|
|
139
|
+
|
|
140
|
+
def characterize_segment(
|
|
141
|
+
self,
|
|
142
|
+
metric_name: str,
|
|
143
|
+
metric_history: List[float],
|
|
144
|
+
change_points: List[int]
|
|
145
|
+
) -> List[Dict[str, Any]]:
|
|
146
|
+
"""
|
|
147
|
+
Characterize segments between change points.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
metric_name: Name of the metric
|
|
151
|
+
metric_history: Historical values
|
|
152
|
+
change_points: List of change point indices
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List of segment characterizations
|
|
156
|
+
"""
|
|
157
|
+
if not change_points:
|
|
158
|
+
return []
|
|
159
|
+
|
|
160
|
+
segments = []
|
|
161
|
+
signal = np.array(metric_history)
|
|
162
|
+
|
|
163
|
+
prev_cp = 0
|
|
164
|
+
for cp in change_points + [len(signal)]:
|
|
165
|
+
segment = signal[prev_cp:cp]
|
|
166
|
+
if len(segment) > 0:
|
|
167
|
+
trend_val = float(np.polyfit(range(len(segment)), segment, 1)[0]) if len(segment) > 1 else 0.0
|
|
168
|
+
segments.append({
|
|
169
|
+
"start": prev_cp,
|
|
170
|
+
"end": cp,
|
|
171
|
+
"mean": float(np.mean(segment)),
|
|
172
|
+
"std": float(np.std(segment)),
|
|
173
|
+
"trend": trend_val,
|
|
174
|
+
"length": len(segment)
|
|
175
|
+
})
|
|
176
|
+
prev_cp = cp
|
|
177
|
+
|
|
178
|
+
return segments
|
|
179
|
+
|
|
180
|
+
def detect_drift(
|
|
181
|
+
self,
|
|
182
|
+
metric_name: str,
|
|
183
|
+
metric_history: List[float],
|
|
184
|
+
threshold: float = 0.7
|
|
185
|
+
) -> Tuple[bool, Optional[Dict[str, Any]]]:
|
|
186
|
+
"""
|
|
187
|
+
Detect if drift has occurred in a metric.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
metric_name: Name of the metric
|
|
191
|
+
metric_history: Historical values
|
|
192
|
+
threshold: Confidence threshold for drift detection
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Tuple of (drift_detected, drift_info)
|
|
196
|
+
"""
|
|
197
|
+
change_points, confidence_scores = self.detect_changepoints(metric_name, metric_history)
|
|
198
|
+
|
|
199
|
+
if not change_points:
|
|
200
|
+
return False, None
|
|
201
|
+
|
|
202
|
+
# Check if most recent change point has high confidence
|
|
203
|
+
if confidence_scores:
|
|
204
|
+
max_confidence = max(confidence_scores)
|
|
205
|
+
if max_confidence >= threshold:
|
|
206
|
+
# Get most recent change point
|
|
207
|
+
recent_cp = change_points[-1]
|
|
208
|
+
segments = self.characterize_segment(metric_name, metric_history, change_points)
|
|
209
|
+
|
|
210
|
+
drift_info = {
|
|
211
|
+
"change_point": recent_cp,
|
|
212
|
+
"confidence": max_confidence,
|
|
213
|
+
"segments": segments,
|
|
214
|
+
"type": self._classify_drift_type(segments) if segments else "unknown"
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return True, drift_info
|
|
218
|
+
|
|
219
|
+
return False, None
|
|
220
|
+
|
|
221
|
+
def _classify_drift_type(self, segments: List[Dict[str, Any]]) -> str:
|
|
222
|
+
"""Classify type of drift (mean shift, variance change, trend change)."""
|
|
223
|
+
if len(segments) < 2:
|
|
224
|
+
return "unknown"
|
|
225
|
+
|
|
226
|
+
# Compare last two segments
|
|
227
|
+
last_seg = segments[-1]
|
|
228
|
+
prev_seg = segments[-2]
|
|
229
|
+
|
|
230
|
+
mean_diff = abs(last_seg["mean"] - prev_seg["mean"])
|
|
231
|
+
std_diff = abs(last_seg["std"] - prev_seg["std"])
|
|
232
|
+
trend_diff = abs(last_seg["trend"] - prev_seg["trend"])
|
|
233
|
+
|
|
234
|
+
if mean_diff > std_diff and mean_diff > trend_diff:
|
|
235
|
+
return "mean_shift"
|
|
236
|
+
elif std_diff > mean_diff and std_diff > trend_diff:
|
|
237
|
+
return "variance_change"
|
|
238
|
+
elif trend_diff > mean_diff and trend_diff > std_diff:
|
|
239
|
+
return "trend_change"
|
|
240
|
+
else:
|
|
241
|
+
return "mixed"
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class HybridDriftDetector:
|
|
245
|
+
"""Hybrid drift detector combining ruptures and CUSUM.
|
|
246
|
+
|
|
247
|
+
Uses ruptures for change-point detection and CUSUM for continuous monitoring.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def __init__(
|
|
251
|
+
self,
|
|
252
|
+
use_ruptures: bool = True,
|
|
253
|
+
cusum_k: float = 0.5,
|
|
254
|
+
cusum_h: float = 5.0,
|
|
255
|
+
ruptures_penalty: float = 10.0
|
|
256
|
+
):
|
|
257
|
+
"""
|
|
258
|
+
Initialize hybrid detector.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
use_ruptures: Whether to use ruptures for detection
|
|
262
|
+
cusum_k: CUSUM threshold parameter
|
|
263
|
+
cusum_h: CUSUM alarm threshold
|
|
264
|
+
ruptures_penalty: Penalty for ruptures algorithm
|
|
265
|
+
"""
|
|
266
|
+
self.use_ruptures = use_ruptures and RUPTURES_AVAILABLE
|
|
267
|
+
self.cusum_k = cusum_k
|
|
268
|
+
self.cusum_h = cusum_h
|
|
269
|
+
self.cusum_stat = 0.0
|
|
270
|
+
|
|
271
|
+
if self.use_ruptures:
|
|
272
|
+
self.ruptures_detector = DriftDetector(penalty=ruptures_penalty)
|
|
273
|
+
else:
|
|
274
|
+
self.ruptures_detector = None
|
|
275
|
+
|
|
276
|
+
def update(
|
|
277
|
+
self,
|
|
278
|
+
metric_name: str,
|
|
279
|
+
x_t: float,
|
|
280
|
+
x_pred: float,
|
|
281
|
+
metric_history: List[float]
|
|
282
|
+
) -> Tuple[bool, Optional[Dict[str, Any]]]:
|
|
283
|
+
"""
|
|
284
|
+
Update drift detection with new observation.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
metric_name: Name of the metric
|
|
288
|
+
x_t: Actual value
|
|
289
|
+
x_pred: Predicted value
|
|
290
|
+
metric_history: Historical values
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
Tuple of (drift_detected, drift_info)
|
|
294
|
+
"""
|
|
295
|
+
# CUSUM update
|
|
296
|
+
residual = abs(x_t - x_pred)
|
|
297
|
+
self.cusum_stat = max(0.0, self.cusum_stat + residual - self.cusum_k)
|
|
298
|
+
|
|
299
|
+
cusum_alarm = self.cusum_stat > self.cusum_h
|
|
300
|
+
|
|
301
|
+
# Ruptures detection (if enabled and enough history)
|
|
302
|
+
ruptures_drift = False
|
|
303
|
+
ruptures_info = None
|
|
304
|
+
|
|
305
|
+
if self.use_ruptures and len(metric_history) >= 10:
|
|
306
|
+
ruptures_drift, ruptures_info = self.ruptures_detector.detect_drift(
|
|
307
|
+
metric_name, metric_history, threshold=0.7
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
# Combine results
|
|
311
|
+
if ruptures_drift or cusum_alarm:
|
|
312
|
+
drift_info = {
|
|
313
|
+
"cusum_stat": self.cusum_stat,
|
|
314
|
+
"cusum_alarm": cusum_alarm,
|
|
315
|
+
"ruptures_drift": ruptures_drift,
|
|
316
|
+
"ruptures_info": ruptures_info
|
|
317
|
+
}
|
|
318
|
+
return True, drift_info
|
|
319
|
+
|
|
320
|
+
return False, None
|
|
321
|
+
|
|
322
|
+
def reset(self) -> None:
|
|
323
|
+
"""Reset CUSUM statistic."""
|
|
324
|
+
self.cusum_stat = 0.0
|
|
325
|
+
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example: Causal Agent Template
|
|
3
|
+
|
|
4
|
+
This demonstrates how to create a causal reasoning agent using the template framework.
|
|
5
|
+
This is a simplified example showing the pattern - the full CRCA.py can be refactored
|
|
6
|
+
to use this pattern.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Dict, Any, List, Tuple, Optional, Union
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from templates.base_specialized_agent import BaseSpecializedAgent
|
|
12
|
+
from templates.graph_management import GraphManager
|
|
13
|
+
from templates.prediction_framework import PredictionFramework, CounterfactualScenario
|
|
14
|
+
from templates.statistical_methods import StatisticalMethods
|
|
15
|
+
from templates.llm_integration import LLMIntegration, create_default_schema
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CausalRelationType(Enum):
|
|
19
|
+
"""Types of causal relationships."""
|
|
20
|
+
DIRECT = "direct"
|
|
21
|
+
INDIRECT = "indirect"
|
|
22
|
+
CONFOUNDING = "confounding"
|
|
23
|
+
MEDIATING = "mediating"
|
|
24
|
+
MODERATING = "moderating"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CausalAgentTemplate(BaseSpecializedAgent):
|
|
28
|
+
"""
|
|
29
|
+
Example causal reasoning agent using the template framework.
|
|
30
|
+
|
|
31
|
+
This demonstrates the pattern for creating specialized agents:
|
|
32
|
+
1. Inherit from BaseSpecializedAgent
|
|
33
|
+
2. Use composition with extracted modules
|
|
34
|
+
3. Implement domain-specific methods
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
variables: Optional[List[str]] = None,
|
|
40
|
+
causal_edges: Optional[List[Tuple[str, str]]] = None,
|
|
41
|
+
max_loops: Optional[Union[int, str]] = 3,
|
|
42
|
+
agent_name: str = "causal-agent",
|
|
43
|
+
agent_description: str = "Causal Reasoning Agent",
|
|
44
|
+
model_name: str = "gpt-4o",
|
|
45
|
+
use_nonlinear: bool = True,
|
|
46
|
+
**kwargs,
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
Initialize the causal agent.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
variables: List of variable names
|
|
53
|
+
causal_edges: List of (source, target) edge tuples
|
|
54
|
+
max_loops: Maximum reasoning loops
|
|
55
|
+
agent_name: Agent identifier
|
|
56
|
+
agent_description: Agent description
|
|
57
|
+
model_name: LLM model name
|
|
58
|
+
use_nonlinear: Whether to use nonlinear prediction
|
|
59
|
+
**kwargs: Additional arguments
|
|
60
|
+
"""
|
|
61
|
+
# Initialize base class
|
|
62
|
+
super().__init__(
|
|
63
|
+
max_loops=max_loops,
|
|
64
|
+
agent_name=agent_name,
|
|
65
|
+
agent_description=agent_description,
|
|
66
|
+
model_name=model_name,
|
|
67
|
+
**kwargs,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Initialize graph manager
|
|
71
|
+
self.graph_manager = GraphManager(graph_type="causal")
|
|
72
|
+
|
|
73
|
+
# Initialize prediction framework
|
|
74
|
+
self.prediction_framework = PredictionFramework(
|
|
75
|
+
graph_manager=self.graph_manager,
|
|
76
|
+
use_nonlinear=use_nonlinear,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Initialize statistical methods
|
|
80
|
+
self.statistical_methods = StatisticalMethods(
|
|
81
|
+
graph_manager=self.graph_manager,
|
|
82
|
+
prediction_framework=self.prediction_framework,
|
|
83
|
+
standardization_stats=self.prediction_framework.standardization_stats,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Initialize LLM integration
|
|
87
|
+
self.llm_integration = LLMIntegration(
|
|
88
|
+
agent=self,
|
|
89
|
+
max_loops=self.domain_max_loops if isinstance(self.domain_max_loops, int) else 3,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Add variables and edges
|
|
93
|
+
if variables:
|
|
94
|
+
self.graph_manager.add_nodes_from(variables)
|
|
95
|
+
|
|
96
|
+
if causal_edges:
|
|
97
|
+
for source, target in causal_edges:
|
|
98
|
+
self.add_causal_relationship(source, target)
|
|
99
|
+
|
|
100
|
+
def _get_domain_schema(self) -> Optional[Dict[str, Any]]:
|
|
101
|
+
"""Return the causal analysis schema."""
|
|
102
|
+
return create_default_schema(
|
|
103
|
+
function_name="generate_causal_analysis",
|
|
104
|
+
description="Generates structured causal reasoning and counterfactual analysis",
|
|
105
|
+
properties={
|
|
106
|
+
"causal_analysis": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"description": "Analysis of causal relationships and mechanisms"
|
|
109
|
+
},
|
|
110
|
+
"intervention_planning": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"description": "Planned interventions to test causal hypotheses"
|
|
113
|
+
},
|
|
114
|
+
"counterfactual_scenarios": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"properties": {
|
|
119
|
+
"scenario_name": {"type": "string"},
|
|
120
|
+
"interventions": {"type": "object"},
|
|
121
|
+
"expected_outcomes": {"type": "object"},
|
|
122
|
+
"reasoning": {"type": "string"}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"description": "Multiple counterfactual scenarios to explore"
|
|
126
|
+
},
|
|
127
|
+
"causal_strength_assessment": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"description": "Assessment of causal relationship strengths and confounders"
|
|
130
|
+
},
|
|
131
|
+
"optimal_solution": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"description": "Recommended optimal solution based on causal analysis"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
required=[
|
|
137
|
+
"causal_analysis",
|
|
138
|
+
"intervention_planning",
|
|
139
|
+
"counterfactual_scenarios",
|
|
140
|
+
"causal_strength_assessment",
|
|
141
|
+
"optimal_solution"
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def _build_domain_prompt(self, task: str) -> str:
|
|
146
|
+
"""Build a causal reasoning prompt."""
|
|
147
|
+
return (
|
|
148
|
+
f"You are a Causal Reasoning with Counterfactual Analysis (CR-CA) agent.\n"
|
|
149
|
+
f"Problem: {task}\n"
|
|
150
|
+
f"Current causal graph has {len(self.graph_manager.get_nodes())} variables and "
|
|
151
|
+
f"{len(self.graph_manager.get_edges())} relationships.\n"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def _domain_specific_setup(self) -> None:
|
|
155
|
+
"""Set up domain-specific attributes."""
|
|
156
|
+
# Causal-specific setup can go here
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
def add_causal_relationship(
|
|
160
|
+
self,
|
|
161
|
+
source: str,
|
|
162
|
+
target: str,
|
|
163
|
+
strength: float = 1.0,
|
|
164
|
+
relation_type: CausalRelationType = CausalRelationType.DIRECT,
|
|
165
|
+
confidence: float = 1.0
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Add a causal relationship."""
|
|
168
|
+
self.graph_manager.add_relationship(
|
|
169
|
+
source=source,
|
|
170
|
+
target=target,
|
|
171
|
+
strength=strength,
|
|
172
|
+
relation_type=relation_type,
|
|
173
|
+
confidence=confidence,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
def predict_outcomes(
|
|
177
|
+
self,
|
|
178
|
+
factual_state: Dict[str, float],
|
|
179
|
+
interventions: Dict[str, float]
|
|
180
|
+
) -> Dict[str, float]:
|
|
181
|
+
"""Predict outcomes given state and interventions."""
|
|
182
|
+
return self.prediction_framework.predict_outcomes(factual_state, interventions)
|
|
183
|
+
|
|
184
|
+
def generate_counterfactual_scenarios(
|
|
185
|
+
self,
|
|
186
|
+
factual_state: Dict[str, float],
|
|
187
|
+
target_variables: List[str],
|
|
188
|
+
max_scenarios: int = 5
|
|
189
|
+
) -> List[CounterfactualScenario]:
|
|
190
|
+
"""Generate counterfactual scenarios."""
|
|
191
|
+
return self.prediction_framework.generate_counterfactual_scenarios(
|
|
192
|
+
factual_state, target_variables, max_scenarios
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def run(
|
|
196
|
+
self,
|
|
197
|
+
task: Optional[Union[str, Any]] = None,
|
|
198
|
+
initial_state: Optional[Any] = None,
|
|
199
|
+
target_variables: Optional[List[str]] = None,
|
|
200
|
+
max_steps: Union[int, str] = 1,
|
|
201
|
+
**kwargs,
|
|
202
|
+
) -> Dict[str, Any]:
|
|
203
|
+
"""
|
|
204
|
+
Run the agent with either LLM analysis or state evolution.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
task: Task string for LLM analysis, or state dict
|
|
208
|
+
initial_state: Initial state dictionary
|
|
209
|
+
target_variables: Target variables for counterfactuals
|
|
210
|
+
max_steps: Maximum evolution steps
|
|
211
|
+
**kwargs: Additional arguments
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Dictionary with results
|
|
215
|
+
"""
|
|
216
|
+
# LLM-based analysis
|
|
217
|
+
if task is not None and isinstance(task, str) and initial_state is None and not task.strip().startswith('{'):
|
|
218
|
+
return self.llm_integration.run_llm_domain_analysis(
|
|
219
|
+
task,
|
|
220
|
+
build_prompt_fn=self._build_domain_prompt,
|
|
221
|
+
post_process_fn=self._post_process_llm_results,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# State evolution
|
|
225
|
+
if task is not None and initial_state is None:
|
|
226
|
+
initial_state = task
|
|
227
|
+
|
|
228
|
+
if not isinstance(initial_state, dict):
|
|
229
|
+
try:
|
|
230
|
+
import json
|
|
231
|
+
parsed = json.loads(initial_state)
|
|
232
|
+
if isinstance(parsed, dict):
|
|
233
|
+
initial_state = parsed
|
|
234
|
+
else:
|
|
235
|
+
return {"error": "initial_state JSON must decode to a dict"}
|
|
236
|
+
except Exception:
|
|
237
|
+
return {"error": "initial_state must be a dict or JSON-encoded dict"}
|
|
238
|
+
|
|
239
|
+
if target_variables is None:
|
|
240
|
+
target_variables = self.graph_manager.get_nodes()
|
|
241
|
+
|
|
242
|
+
def _resolve_max_steps(value: Union[int, str]) -> int:
|
|
243
|
+
if isinstance(value, str) and value == "auto":
|
|
244
|
+
return max(1, len(self.graph_manager.get_nodes()))
|
|
245
|
+
try:
|
|
246
|
+
return int(value)
|
|
247
|
+
except Exception:
|
|
248
|
+
return max(1, len(self.graph_manager.get_nodes()))
|
|
249
|
+
|
|
250
|
+
effective_steps = _resolve_max_steps(max_steps)
|
|
251
|
+
current_state = initial_state.copy()
|
|
252
|
+
for step in range(effective_steps):
|
|
253
|
+
current_state = self.prediction_framework.predict_outcomes(current_state, {})
|
|
254
|
+
|
|
255
|
+
self.prediction_framework.ensure_standardization_stats(current_state)
|
|
256
|
+
counterfactual_scenarios = self.generate_counterfactual_scenarios(
|
|
257
|
+
current_state,
|
|
258
|
+
target_variables,
|
|
259
|
+
max_scenarios=5
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
"initial_state": initial_state,
|
|
264
|
+
"evolved_state": current_state,
|
|
265
|
+
"counterfactual_scenarios": counterfactual_scenarios,
|
|
266
|
+
"graph_info": {
|
|
267
|
+
"nodes": self.graph_manager.get_nodes(),
|
|
268
|
+
"edges": self.graph_manager.get_edges(),
|
|
269
|
+
"is_dag": self.graph_manager.is_dag()
|
|
270
|
+
},
|
|
271
|
+
"steps": effective_steps
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
def _post_process_llm_results(self, results: Dict[str, Any]) -> Dict[str, Any]:
|
|
275
|
+
"""Post-process LLM analysis results."""
|
|
276
|
+
default_state = {var: 0.0 for var in self.graph_manager.get_nodes()}
|
|
277
|
+
self.prediction_framework.ensure_standardization_stats(default_state)
|
|
278
|
+
counterfactual_scenarios = self.generate_counterfactual_scenarios(
|
|
279
|
+
default_state,
|
|
280
|
+
self.graph_manager.get_nodes()[:5],
|
|
281
|
+
max_scenarios=5
|
|
282
|
+
)
|
|
283
|
+
results['counterfactual_scenarios'] = counterfactual_scenarios
|
|
284
|
+
results['graph_info'] = {
|
|
285
|
+
'nodes': self.graph_manager.get_nodes(),
|
|
286
|
+
'edges': self.graph_manager.get_edges(),
|
|
287
|
+
'is_dag': self.graph_manager.is_dag()
|
|
288
|
+
}
|
|
289
|
+
return results
|
|
290
|
+
|
|
291
|
+
# Convenience methods that delegate to modules
|
|
292
|
+
def get_nodes(self) -> List[str]:
|
|
293
|
+
"""Get all nodes."""
|
|
294
|
+
return self.graph_manager.get_nodes()
|
|
295
|
+
|
|
296
|
+
def get_edges(self) -> List[Tuple[str, str]]:
|
|
297
|
+
"""Get all edges."""
|
|
298
|
+
return self.graph_manager.get_edges()
|
|
299
|
+
|
|
300
|
+
def is_dag(self) -> bool:
|
|
301
|
+
"""Check if graph is a DAG."""
|
|
302
|
+
return self.graph_manager.is_dag()
|
|
303
|
+
|
|
304
|
+
def fit_from_dataframe(self, df: Any, variables: List[str], **kwargs) -> None:
|
|
305
|
+
"""Fit model from dataframe."""
|
|
306
|
+
self.statistical_methods.fit_from_dataframe(df, variables, **kwargs)
|
|
307
|
+
# Update prediction framework stats
|
|
308
|
+
self.prediction_framework.standardization_stats = self.statistical_methods.standardization_stats
|
|
309
|
+
|