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,253 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Feature Mixins for Drag-and-Drop Composition
|
|
3
|
+
|
|
4
|
+
Provides mixin classes that can be easily mixed into agents to add capabilities.
|
|
5
|
+
Each mixin is self-contained and can be used independently.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Any, List, Optional, TYPE_CHECKING
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .base_specialized_agent import BaseSpecializedAgent
|
|
13
|
+
from .graph_management import GraphManager
|
|
14
|
+
from .prediction_framework import PredictionFramework
|
|
15
|
+
from .statistical_methods import StatisticalMethods
|
|
16
|
+
from .llm_integration import LLMIntegration
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GraphFeatureMixin:
|
|
22
|
+
"""
|
|
23
|
+
Mixin to add graph management capabilities.
|
|
24
|
+
|
|
25
|
+
Usage:
|
|
26
|
+
class MyAgent(BaseSpecializedAgent, GraphFeatureMixin):
|
|
27
|
+
def __init__(self, **kwargs):
|
|
28
|
+
super().__init__(**kwargs)
|
|
29
|
+
self.init_graph_feature(graph_type='causal')
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def init_graph_feature(
|
|
33
|
+
self,
|
|
34
|
+
graph_type: str = "causal",
|
|
35
|
+
variables: Optional[List[str]] = None,
|
|
36
|
+
edges: Optional[List[tuple]] = None,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Initialize graph feature.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
graph_type: Type of graph
|
|
43
|
+
variables: Optional list of variables
|
|
44
|
+
edges: Optional list of (source, target) tuples
|
|
45
|
+
"""
|
|
46
|
+
from .graph_management import GraphManager
|
|
47
|
+
|
|
48
|
+
self.graph_manager = GraphManager(graph_type=graph_type)
|
|
49
|
+
|
|
50
|
+
if variables:
|
|
51
|
+
self.graph_manager.add_nodes_from(variables)
|
|
52
|
+
if edges:
|
|
53
|
+
self.graph_manager.add_edges_from(edges)
|
|
54
|
+
|
|
55
|
+
# Convenience methods
|
|
56
|
+
def add_node(self, node: str) -> None:
|
|
57
|
+
"""Add a node to the graph."""
|
|
58
|
+
if hasattr(self, 'graph_manager'):
|
|
59
|
+
self.graph_manager.ensure_node_exists(node)
|
|
60
|
+
|
|
61
|
+
def add_edge(self, source: str, target: str, **metadata) -> None:
|
|
62
|
+
"""Add an edge to the graph."""
|
|
63
|
+
if hasattr(self, 'graph_manager'):
|
|
64
|
+
self.graph_manager.add_relationship(source, target, **metadata)
|
|
65
|
+
|
|
66
|
+
def get_nodes(self) -> List[str]:
|
|
67
|
+
"""Get all nodes."""
|
|
68
|
+
if hasattr(self, 'graph_manager'):
|
|
69
|
+
return self.graph_manager.get_nodes()
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
def get_edges(self) -> List[tuple]:
|
|
73
|
+
"""Get all edges."""
|
|
74
|
+
if hasattr(self, 'graph_manager'):
|
|
75
|
+
return self.graph_manager.get_edges()
|
|
76
|
+
return []
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class PredictionFeatureMixin:
|
|
80
|
+
"""
|
|
81
|
+
Mixin to add prediction capabilities.
|
|
82
|
+
|
|
83
|
+
Usage:
|
|
84
|
+
class MyAgent(BaseSpecializedAgent, GraphFeatureMixin, PredictionFeatureMixin):
|
|
85
|
+
def __init__(self, **kwargs):
|
|
86
|
+
super().__init__(**kwargs)
|
|
87
|
+
self.init_graph_feature()
|
|
88
|
+
self.init_prediction_feature()
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def init_prediction_feature(
|
|
92
|
+
self,
|
|
93
|
+
use_nonlinear: bool = True,
|
|
94
|
+
cache_enabled: bool = True,
|
|
95
|
+
**kwargs
|
|
96
|
+
) -> None:
|
|
97
|
+
"""
|
|
98
|
+
Initialize prediction feature.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
use_nonlinear: Whether to use nonlinear predictions
|
|
102
|
+
cache_enabled: Whether to enable caching
|
|
103
|
+
**kwargs: Additional prediction framework config
|
|
104
|
+
"""
|
|
105
|
+
from .prediction_framework import PredictionFramework
|
|
106
|
+
|
|
107
|
+
if not hasattr(self, 'graph_manager'):
|
|
108
|
+
raise ValueError("GraphFeatureMixin required before PredictionFeatureMixin")
|
|
109
|
+
|
|
110
|
+
self.prediction_framework = PredictionFramework(
|
|
111
|
+
graph_manager=self.graph_manager,
|
|
112
|
+
use_nonlinear=use_nonlinear,
|
|
113
|
+
cache_enabled=cache_enabled,
|
|
114
|
+
**kwargs
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def predict(self, state: Dict[str, float], interventions: Optional[Dict[str, float]] = None) -> Dict[str, float]:
|
|
118
|
+
"""Predict outcomes."""
|
|
119
|
+
if hasattr(self, 'prediction_framework'):
|
|
120
|
+
return self.prediction_framework.predict_outcomes(state, interventions or {})
|
|
121
|
+
raise AttributeError("Prediction feature not initialized. Call init_prediction_feature() first.")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class StatisticsFeatureMixin:
|
|
125
|
+
"""
|
|
126
|
+
Mixin to add statistical analysis capabilities.
|
|
127
|
+
|
|
128
|
+
Usage:
|
|
129
|
+
class MyAgent(BaseSpecializedAgent, GraphFeatureMixin, PredictionFeatureMixin, StatisticsFeatureMixin):
|
|
130
|
+
def __init__(self, **kwargs):
|
|
131
|
+
super().__init__(**kwargs)
|
|
132
|
+
self.init_graph_feature()
|
|
133
|
+
self.init_prediction_feature()
|
|
134
|
+
self.init_statistics_feature()
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
def init_statistics_feature(
|
|
138
|
+
self,
|
|
139
|
+
seed: int = 42,
|
|
140
|
+
bootstrap_workers: int = 0,
|
|
141
|
+
**kwargs
|
|
142
|
+
) -> None:
|
|
143
|
+
"""
|
|
144
|
+
Initialize statistics feature.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
seed: Random seed
|
|
148
|
+
bootstrap_workers: Number of bootstrap workers
|
|
149
|
+
**kwargs: Additional statistics config
|
|
150
|
+
"""
|
|
151
|
+
from .statistical_methods import StatisticalMethods
|
|
152
|
+
|
|
153
|
+
if not hasattr(self, 'graph_manager'):
|
|
154
|
+
raise ValueError("GraphFeatureMixin required before StatisticsFeatureMixin")
|
|
155
|
+
if not hasattr(self, 'prediction_framework'):
|
|
156
|
+
raise ValueError("PredictionFeatureMixin required before StatisticsFeatureMixin")
|
|
157
|
+
|
|
158
|
+
self.statistical_methods = StatisticalMethods(
|
|
159
|
+
graph_manager=self.graph_manager,
|
|
160
|
+
prediction_framework=self.prediction_framework,
|
|
161
|
+
standardization_stats=getattr(self.prediction_framework, 'standardization_stats', {}),
|
|
162
|
+
seed=seed,
|
|
163
|
+
bootstrap_workers=bootstrap_workers,
|
|
164
|
+
**kwargs
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def fit_from_data(self, df: Any, variables: List[str], **kwargs) -> None:
|
|
168
|
+
"""Fit model from data."""
|
|
169
|
+
if hasattr(self, 'statistical_methods'):
|
|
170
|
+
self.statistical_methods.fit_from_dataframe(df, variables, **kwargs)
|
|
171
|
+
else:
|
|
172
|
+
raise AttributeError("Statistics feature not initialized. Call init_statistics_feature() first.")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class LLMFeatureMixin:
|
|
176
|
+
"""
|
|
177
|
+
Mixin to add LLM integration capabilities.
|
|
178
|
+
|
|
179
|
+
Usage:
|
|
180
|
+
class MyAgent(BaseSpecializedAgent, LLMFeatureMixin):
|
|
181
|
+
def __init__(self, **kwargs):
|
|
182
|
+
super().__init__(**kwargs)
|
|
183
|
+
self.init_llm_feature()
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def init_llm_feature(
|
|
187
|
+
self,
|
|
188
|
+
max_loops: Optional[int] = None,
|
|
189
|
+
**kwargs
|
|
190
|
+
) -> None:
|
|
191
|
+
"""
|
|
192
|
+
Initialize LLM feature.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
max_loops: Maximum reasoning loops
|
|
196
|
+
**kwargs: Additional LLM config
|
|
197
|
+
"""
|
|
198
|
+
from .llm_integration import LLMIntegration
|
|
199
|
+
|
|
200
|
+
max_loops = max_loops or getattr(self, 'domain_max_loops', 3)
|
|
201
|
+
|
|
202
|
+
self.llm_integration = LLMIntegration(
|
|
203
|
+
agent=self,
|
|
204
|
+
max_loops=max_loops,
|
|
205
|
+
**kwargs
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def analyze_with_llm(self, task: str, **kwargs) -> Dict[str, Any]:
|
|
209
|
+
"""Run LLM-based analysis."""
|
|
210
|
+
if hasattr(self, 'llm_integration'):
|
|
211
|
+
return self.llm_integration.run_llm_domain_analysis(
|
|
212
|
+
task,
|
|
213
|
+
build_prompt_fn=getattr(self, '_build_domain_prompt', None),
|
|
214
|
+
**kwargs
|
|
215
|
+
)
|
|
216
|
+
raise AttributeError("LLM feature not initialized. Call init_llm_feature() first.")
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# Convenience: All-in-one mixin
|
|
220
|
+
class FullFeatureMixin(GraphFeatureMixin, PredictionFeatureMixin, StatisticsFeatureMixin, LLMFeatureMixin):
|
|
221
|
+
"""
|
|
222
|
+
Mixin that includes all features.
|
|
223
|
+
|
|
224
|
+
Usage:
|
|
225
|
+
class MyAgent(BaseSpecializedAgent, FullFeatureMixin):
|
|
226
|
+
def __init__(self, **kwargs):
|
|
227
|
+
super().__init__(**kwargs)
|
|
228
|
+
self.init_all_features()
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
def init_all_features(
|
|
232
|
+
self,
|
|
233
|
+
graph_type: str = "causal",
|
|
234
|
+
use_nonlinear: bool = True,
|
|
235
|
+
variables: Optional[List[str]] = None,
|
|
236
|
+
edges: Optional[List[tuple]] = None,
|
|
237
|
+
**kwargs
|
|
238
|
+
) -> None:
|
|
239
|
+
"""
|
|
240
|
+
Initialize all features at once.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
graph_type: Type of graph
|
|
244
|
+
use_nonlinear: Whether to use nonlinear predictions
|
|
245
|
+
variables: Optional list of variables
|
|
246
|
+
edges: Optional list of edges
|
|
247
|
+
**kwargs: Additional config for individual features
|
|
248
|
+
"""
|
|
249
|
+
self.init_graph_feature(graph_type=graph_type, variables=variables, edges=edges)
|
|
250
|
+
self.init_prediction_feature(use_nonlinear=use_nonlinear, **kwargs.get('prediction', {}))
|
|
251
|
+
self.init_statistics_feature(**kwargs.get('statistics', {}))
|
|
252
|
+
self.init_llm_feature(**kwargs.get('llm', {}))
|
|
253
|
+
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Graph management module for specialized agents.
|
|
3
|
+
|
|
4
|
+
Provides graph operations including node/edge management, topological sorting,
|
|
5
|
+
path finding, and DAG validation. Supports both dict-based and rustworkx-based graphs.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, List, Tuple, Optional, Any
|
|
9
|
+
import logging
|
|
10
|
+
from enum import Enum
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import rustworkx as rx
|
|
14
|
+
RUSTWORKX_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
RUSTWORKX_AVAILABLE = False
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GraphManager:
|
|
22
|
+
"""
|
|
23
|
+
Manages graph operations for specialized agents.
|
|
24
|
+
|
|
25
|
+
Supports both dict-based graphs (always available) and rustworkx-based
|
|
26
|
+
graphs (when rustworkx is installed). Falls back gracefully to dict-only
|
|
27
|
+
operations when rustworkx is unavailable.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, graph_type: str = "causal"):
|
|
31
|
+
"""
|
|
32
|
+
Initialize the graph manager.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
graph_type: Type of graph (causal, knowledge, dependency, etc.)
|
|
36
|
+
"""
|
|
37
|
+
self.graph_type = graph_type
|
|
38
|
+
self.graph: Dict[str, Dict[str, Any]] = {}
|
|
39
|
+
self.graph_reverse: Dict[str, List[str]] = {} # For fast parent lookup
|
|
40
|
+
|
|
41
|
+
# Rustworkx graph (optional)
|
|
42
|
+
self._rustworkx_graph = None
|
|
43
|
+
self._node_to_index: Dict[str, int] = {}
|
|
44
|
+
self._index_to_node: Dict[int, str] = {}
|
|
45
|
+
|
|
46
|
+
if RUSTWORKX_AVAILABLE:
|
|
47
|
+
try:
|
|
48
|
+
self._rustworkx_graph = rx.PyDiGraph()
|
|
49
|
+
except Exception:
|
|
50
|
+
logger.warning("Failed to initialize rustworkx graph, using dict-only mode")
|
|
51
|
+
self._rustworkx_graph = None
|
|
52
|
+
|
|
53
|
+
def ensure_node_exists(self, node: str) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Ensure a node exists in the graph.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
node: Node identifier
|
|
59
|
+
"""
|
|
60
|
+
if node not in self.graph:
|
|
61
|
+
self.graph[node] = {}
|
|
62
|
+
if node not in self.graph_reverse:
|
|
63
|
+
self.graph_reverse[node] = []
|
|
64
|
+
try:
|
|
65
|
+
self._ensure_node_index(node)
|
|
66
|
+
except Exception:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
def add_relationship(
|
|
70
|
+
self,
|
|
71
|
+
source: str,
|
|
72
|
+
target: str,
|
|
73
|
+
strength: float = 1.0,
|
|
74
|
+
relation_type: Optional[Any] = None,
|
|
75
|
+
confidence: float = 1.0,
|
|
76
|
+
**metadata
|
|
77
|
+
) -> None:
|
|
78
|
+
"""
|
|
79
|
+
Add a relationship between two nodes.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
source: Source node
|
|
83
|
+
target: Target node
|
|
84
|
+
strength: Relationship strength
|
|
85
|
+
relation_type: Type of relationship (can be Enum or string)
|
|
86
|
+
confidence: Confidence in the relationship
|
|
87
|
+
**metadata: Additional metadata to store
|
|
88
|
+
"""
|
|
89
|
+
self.ensure_node_exists(source)
|
|
90
|
+
self.ensure_node_exists(target)
|
|
91
|
+
|
|
92
|
+
meta = {
|
|
93
|
+
"strength": float(strength),
|
|
94
|
+
"confidence": float(confidence),
|
|
95
|
+
**metadata
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if relation_type is not None:
|
|
99
|
+
if isinstance(relation_type, Enum):
|
|
100
|
+
meta["relation_type"] = relation_type.value
|
|
101
|
+
else:
|
|
102
|
+
meta["relation_type"] = str(relation_type)
|
|
103
|
+
|
|
104
|
+
self.graph.setdefault(source, {})[target] = meta
|
|
105
|
+
|
|
106
|
+
if source not in self.graph_reverse.get(target, []):
|
|
107
|
+
self.graph_reverse.setdefault(target, []).append(source)
|
|
108
|
+
|
|
109
|
+
# Update rustworkx graph if available
|
|
110
|
+
if self._rustworkx_graph is not None:
|
|
111
|
+
try:
|
|
112
|
+
u_idx = self._ensure_node_index(source)
|
|
113
|
+
v_idx = self._ensure_node_index(target)
|
|
114
|
+
try:
|
|
115
|
+
existing = self._rustworkx_graph.get_edge_data(u_idx, v_idx)
|
|
116
|
+
except Exception:
|
|
117
|
+
existing = None
|
|
118
|
+
|
|
119
|
+
if existing is None:
|
|
120
|
+
try:
|
|
121
|
+
self._rustworkx_graph.add_edge(u_idx, v_idx, meta)
|
|
122
|
+
except Exception:
|
|
123
|
+
logger.debug(
|
|
124
|
+
f"rustworkx.add_edge failed for {source}->{target}; continuing with dict-only graph."
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
try:
|
|
128
|
+
if isinstance(existing, dict):
|
|
129
|
+
existing.update(meta)
|
|
130
|
+
else:
|
|
131
|
+
try:
|
|
132
|
+
edge_idx = self._rustworkx_graph.get_edge_index(u_idx, v_idx)
|
|
133
|
+
except Exception:
|
|
134
|
+
edge_idx = None
|
|
135
|
+
if edge_idx is not None and edge_idx >= 0:
|
|
136
|
+
try:
|
|
137
|
+
self._rustworkx_graph.remove_edge(edge_idx)
|
|
138
|
+
self._rustworkx_graph.add_edge(u_idx, v_idx, meta)
|
|
139
|
+
except Exception:
|
|
140
|
+
logger.debug(
|
|
141
|
+
f"Could not replace rustworkx edge for {source}->{target}; keeping dict-only metadata."
|
|
142
|
+
)
|
|
143
|
+
except Exception:
|
|
144
|
+
logger.debug(
|
|
145
|
+
f"Failed updating rustworkx edge for {source}->{target}; continuing with dict-only graph."
|
|
146
|
+
)
|
|
147
|
+
except Exception:
|
|
148
|
+
logger.debug(
|
|
149
|
+
"rustworkx operation failed during add_relationship; continuing with dict-only graph."
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def get_parents(self, node: str) -> List[str]:
|
|
153
|
+
"""
|
|
154
|
+
Get parent nodes of a given node.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
node: Node identifier
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
List of parent node identifiers
|
|
161
|
+
"""
|
|
162
|
+
return self.graph_reverse.get(node, [])
|
|
163
|
+
|
|
164
|
+
def get_children(self, node: str) -> List[str]:
|
|
165
|
+
"""
|
|
166
|
+
Get child nodes of a given node.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
node: Node identifier
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
List of child node identifiers
|
|
173
|
+
"""
|
|
174
|
+
return list(self.graph.get(node, {}).keys())
|
|
175
|
+
|
|
176
|
+
def _ensure_node_index(self, name: str) -> int:
|
|
177
|
+
"""
|
|
178
|
+
Ensure a node has an index in the rustworkx graph.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
name: Node identifier
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Node index
|
|
185
|
+
"""
|
|
186
|
+
if name in self._node_to_index:
|
|
187
|
+
return self._node_to_index[name]
|
|
188
|
+
if self._rustworkx_graph is None:
|
|
189
|
+
raise RuntimeError("rustworkx graph not available")
|
|
190
|
+
idx = self._rustworkx_graph.add_node(name)
|
|
191
|
+
self._node_to_index[name] = idx
|
|
192
|
+
self._index_to_node[idx] = name
|
|
193
|
+
return idx
|
|
194
|
+
|
|
195
|
+
def _node_index(self, name: str) -> Optional[int]:
|
|
196
|
+
"""
|
|
197
|
+
Get the rustworkx index for a node.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
name: Node identifier
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Node index or None if not found
|
|
204
|
+
"""
|
|
205
|
+
return self._node_to_index.get(name)
|
|
206
|
+
|
|
207
|
+
def _node_name(self, idx: int) -> Optional[str]:
|
|
208
|
+
"""
|
|
209
|
+
Get the node name for a rustworkx index.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
idx: Node index
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Node identifier or None if not found
|
|
216
|
+
"""
|
|
217
|
+
return self._index_to_node.get(idx)
|
|
218
|
+
|
|
219
|
+
def edge_strength(self, source: str, target: str) -> float:
|
|
220
|
+
"""
|
|
221
|
+
Get the strength of an edge.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
source: Source node
|
|
225
|
+
target: Target node
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Edge strength (0.0 if edge doesn't exist)
|
|
229
|
+
"""
|
|
230
|
+
edge = self.graph.get(source, {}).get(target, None)
|
|
231
|
+
if isinstance(edge, dict):
|
|
232
|
+
return float(edge.get("strength", 0.0))
|
|
233
|
+
try:
|
|
234
|
+
return float(edge) if edge is not None else 0.0
|
|
235
|
+
except Exception:
|
|
236
|
+
return 0.0
|
|
237
|
+
|
|
238
|
+
def topological_sort(self) -> List[str]:
|
|
239
|
+
"""
|
|
240
|
+
Perform topological sort of the graph.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
List of nodes in topological order
|
|
244
|
+
"""
|
|
245
|
+
if self._rustworkx_graph is not None:
|
|
246
|
+
try:
|
|
247
|
+
order_idx = rx.topological_sort(self._rustworkx_graph)
|
|
248
|
+
result = [self._node_name(i) for i in order_idx if self._node_name(i) is not None]
|
|
249
|
+
for n in list(self.graph.keys()):
|
|
250
|
+
if n not in result:
|
|
251
|
+
result.append(n)
|
|
252
|
+
return result
|
|
253
|
+
except Exception:
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
# Fallback to dict-based topological sort
|
|
257
|
+
in_degree: Dict[str, int] = {node: 0 for node in self.graph.keys()}
|
|
258
|
+
for node in self.graph:
|
|
259
|
+
for child in self.get_children(node):
|
|
260
|
+
in_degree[child] = in_degree.get(child, 0) + 1
|
|
261
|
+
|
|
262
|
+
queue: List[str] = [node for node, degree in in_degree.items() if degree == 0]
|
|
263
|
+
result: List[str] = []
|
|
264
|
+
while queue:
|
|
265
|
+
node = queue.pop(0)
|
|
266
|
+
result.append(node)
|
|
267
|
+
for child in self.get_children(node):
|
|
268
|
+
in_degree[child] -= 1
|
|
269
|
+
if in_degree[child] == 0:
|
|
270
|
+
queue.append(child)
|
|
271
|
+
return result
|
|
272
|
+
|
|
273
|
+
def identify_path(self, start: str, end: str) -> List[str]:
|
|
274
|
+
"""
|
|
275
|
+
Find a path from start to end node.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
start: Starting node
|
|
279
|
+
end: Ending node
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
List of nodes forming the path, or empty list if no path exists
|
|
283
|
+
"""
|
|
284
|
+
if start not in self.graph or end not in self.graph:
|
|
285
|
+
return []
|
|
286
|
+
|
|
287
|
+
if start == end:
|
|
288
|
+
return [start]
|
|
289
|
+
|
|
290
|
+
queue: List[Tuple[str, List[str]]] = [(start, [start])]
|
|
291
|
+
visited: set = {start}
|
|
292
|
+
|
|
293
|
+
while queue:
|
|
294
|
+
current, path = queue.pop(0)
|
|
295
|
+
|
|
296
|
+
for child in self.get_children(current):
|
|
297
|
+
if child == end:
|
|
298
|
+
return path + [child]
|
|
299
|
+
|
|
300
|
+
if child not in visited:
|
|
301
|
+
visited.add(child)
|
|
302
|
+
queue.append((child, path + [child]))
|
|
303
|
+
|
|
304
|
+
return [] # No path found
|
|
305
|
+
|
|
306
|
+
def has_path(self, start: str, end: str) -> bool:
|
|
307
|
+
"""
|
|
308
|
+
Check if a path exists from start to end.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
start: Starting node
|
|
312
|
+
end: Ending node
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
True if path exists, False otherwise
|
|
316
|
+
"""
|
|
317
|
+
if start == end:
|
|
318
|
+
return True
|
|
319
|
+
|
|
320
|
+
stack = [start]
|
|
321
|
+
visited = set()
|
|
322
|
+
|
|
323
|
+
while stack:
|
|
324
|
+
current = stack.pop()
|
|
325
|
+
if current in visited:
|
|
326
|
+
continue
|
|
327
|
+
visited.add(current)
|
|
328
|
+
|
|
329
|
+
for child in self.get_children(current):
|
|
330
|
+
if child == end:
|
|
331
|
+
return True
|
|
332
|
+
if child not in visited:
|
|
333
|
+
stack.append(child)
|
|
334
|
+
|
|
335
|
+
return False
|
|
336
|
+
|
|
337
|
+
def get_descendants(self, node: str) -> List[str]:
|
|
338
|
+
"""
|
|
339
|
+
Get all descendant nodes of a given node.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
node: Node identifier
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
List of descendant node identifiers
|
|
346
|
+
"""
|
|
347
|
+
if node not in self.graph:
|
|
348
|
+
return []
|
|
349
|
+
stack = [node]
|
|
350
|
+
visited = set()
|
|
351
|
+
descendants: List[str] = []
|
|
352
|
+
while stack:
|
|
353
|
+
cur = stack.pop()
|
|
354
|
+
for child in self.get_children(cur):
|
|
355
|
+
if child in visited:
|
|
356
|
+
continue
|
|
357
|
+
visited.add(child)
|
|
358
|
+
descendants.append(child)
|
|
359
|
+
stack.append(child)
|
|
360
|
+
return descendants
|
|
361
|
+
|
|
362
|
+
def get_nodes(self) -> List[str]:
|
|
363
|
+
"""
|
|
364
|
+
Get all nodes in the graph.
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
List of node identifiers
|
|
368
|
+
"""
|
|
369
|
+
return list(self.graph.keys())
|
|
370
|
+
|
|
371
|
+
def get_edges(self) -> List[Tuple[str, str]]:
|
|
372
|
+
"""
|
|
373
|
+
Get all edges in the graph.
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
List of (source, target) tuples
|
|
377
|
+
"""
|
|
378
|
+
edges = []
|
|
379
|
+
for source, targets in self.graph.items():
|
|
380
|
+
for target in targets.keys():
|
|
381
|
+
edges.append((source, target))
|
|
382
|
+
return edges
|
|
383
|
+
|
|
384
|
+
def is_dag(self) -> bool:
|
|
385
|
+
"""
|
|
386
|
+
Check if the graph is a directed acyclic graph (DAG).
|
|
387
|
+
|
|
388
|
+
Returns:
|
|
389
|
+
True if DAG, False otherwise
|
|
390
|
+
"""
|
|
391
|
+
if self._rustworkx_graph is not None:
|
|
392
|
+
try:
|
|
393
|
+
return rx.is_directed_acyclic_graph(self._rustworkx_graph)
|
|
394
|
+
except Exception:
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
# Fallback to dict-based cycle detection
|
|
398
|
+
def has_cycle(node: str, visited: set, rec_stack: set) -> bool:
|
|
399
|
+
visited.add(node)
|
|
400
|
+
rec_stack.add(node)
|
|
401
|
+
|
|
402
|
+
for child in self.get_children(node):
|
|
403
|
+
if child not in visited:
|
|
404
|
+
if has_cycle(child, visited, rec_stack):
|
|
405
|
+
return True
|
|
406
|
+
elif child in rec_stack:
|
|
407
|
+
return True
|
|
408
|
+
|
|
409
|
+
rec_stack.remove(node)
|
|
410
|
+
return False
|
|
411
|
+
|
|
412
|
+
visited = set()
|
|
413
|
+
rec_stack = set()
|
|
414
|
+
|
|
415
|
+
for node in self.graph:
|
|
416
|
+
if node not in visited:
|
|
417
|
+
if has_cycle(node, visited, rec_stack):
|
|
418
|
+
return False
|
|
419
|
+
|
|
420
|
+
return True
|
|
421
|
+
|
|
422
|
+
def add_nodes_from(self, nodes: List[str]) -> None:
|
|
423
|
+
"""
|
|
424
|
+
Add multiple nodes to the graph.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
nodes: List of node identifiers
|
|
428
|
+
"""
|
|
429
|
+
for n in nodes:
|
|
430
|
+
self.ensure_node_exists(n)
|
|
431
|
+
|
|
432
|
+
def add_edges_from(self, edges: List[Tuple[str, str]], **default_metadata) -> None:
|
|
433
|
+
"""
|
|
434
|
+
Add multiple edges to the graph.
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
edges: List of (source, target) tuples
|
|
438
|
+
**default_metadata: Default metadata for edges
|
|
439
|
+
"""
|
|
440
|
+
for u, v in edges:
|
|
441
|
+
self.add_relationship(u, v, **default_metadata)
|
|
442
|
+
|