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.
Files changed (501) hide show
  1. .github/ISSUE_TEMPLATE/bug_report.md +65 -0
  2. .github/ISSUE_TEMPLATE/feature_request.md +41 -0
  3. .github/PULL_REQUEST_TEMPLATE.md +20 -0
  4. .github/workflows/publish-manual.yml +61 -0
  5. .github/workflows/publish.yml +64 -0
  6. .gitignore +214 -0
  7. CRCA.py +4156 -0
  8. LICENSE +201 -0
  9. MANIFEST.in +43 -0
  10. PKG-INFO +5035 -0
  11. README.md +4959 -0
  12. __init__.py +17 -0
  13. branches/CRCA-Q.py +2728 -0
  14. branches/crca_cg/corposwarm.py +9065 -0
  15. branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
  16. branches/crca_cg/package.json +5 -0
  17. branches/crca_cg/test_bolt_integration.py +446 -0
  18. branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
  19. branches/crca_cg/test_new_features.py +163 -0
  20. branches/crca_sd/__init__.py +149 -0
  21. branches/crca_sd/crca_sd_core.py +770 -0
  22. branches/crca_sd/crca_sd_governance.py +1325 -0
  23. branches/crca_sd/crca_sd_mpc.py +1130 -0
  24. branches/crca_sd/crca_sd_realtime.py +1844 -0
  25. branches/crca_sd/crca_sd_tui.py +1133 -0
  26. crca-1.4.0.dist-info/METADATA +5035 -0
  27. crca-1.4.0.dist-info/RECORD +501 -0
  28. crca-1.4.0.dist-info/WHEEL +4 -0
  29. crca-1.4.0.dist-info/licenses/LICENSE +201 -0
  30. docs/CRCA-Q.md +2333 -0
  31. examples/config.yaml.example +25 -0
  32. examples/crca_sd_example.py +513 -0
  33. examples/data_broker_example.py +294 -0
  34. examples/logistics_corporation.py +861 -0
  35. examples/palantir_example.py +299 -0
  36. examples/policy_bench.py +934 -0
  37. examples/pridnestrovia-sd.py +705 -0
  38. examples/pridnestrovia_realtime.py +1902 -0
  39. prompts/__init__.py +10 -0
  40. prompts/default_crca.py +101 -0
  41. pyproject.toml +151 -0
  42. requirements.txt +76 -0
  43. schemas/__init__.py +43 -0
  44. schemas/mcpSchemas.py +51 -0
  45. schemas/policy.py +458 -0
  46. templates/__init__.py +38 -0
  47. templates/base_specialized_agent.py +195 -0
  48. templates/drift_detection.py +325 -0
  49. templates/examples/causal_agent_template.py +309 -0
  50. templates/examples/drag_drop_example.py +213 -0
  51. templates/examples/logistics_agent_template.py +207 -0
  52. templates/examples/trading_agent_template.py +206 -0
  53. templates/feature_mixins.py +253 -0
  54. templates/graph_management.py +442 -0
  55. templates/llm_integration.py +194 -0
  56. templates/module_registry.py +276 -0
  57. templates/mpc_planner.py +280 -0
  58. templates/policy_loop.py +1168 -0
  59. templates/prediction_framework.py +448 -0
  60. templates/statistical_methods.py +778 -0
  61. tests/sanity.yml +31 -0
  62. tests/sanity_check +406 -0
  63. tests/test_core.py +47 -0
  64. tests/test_crca_excel.py +166 -0
  65. tests/test_crca_sd.py +780 -0
  66. tests/test_data_broker.py +424 -0
  67. tests/test_palantir.py +349 -0
  68. tools/__init__.py +38 -0
  69. tools/actuators.py +437 -0
  70. tools/bolt.diy/Dockerfile +103 -0
  71. tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
  72. tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
  73. tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
  74. tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
  75. tools/bolt.diy/app/components/@settings/index.ts +12 -0
  76. tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
  77. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
  78. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
  79. tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
  80. tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
  81. tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
  82. tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
  83. tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
  84. tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
  85. tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
  86. tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
  87. tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
  88. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
  89. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
  90. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
  91. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
  92. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
  93. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
  94. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
  95. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
  96. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
  97. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
  98. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
  99. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
  100. tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
  101. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
  102. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
  103. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
  104. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
  105. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
  106. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
  107. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
  108. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
  109. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
  110. tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
  111. tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
  112. tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
  113. tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
  114. tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
  115. tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
  116. tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
  117. tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
  118. tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
  119. tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
  120. tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
  121. tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
  122. tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
  123. tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
  124. tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
  125. tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
  126. tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
  127. tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
  128. tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
  129. tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
  130. tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
  131. tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
  132. tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
  133. tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
  134. tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
  135. tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
  136. tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
  137. tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
  138. tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
  139. tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
  140. tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
  141. tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
  142. tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
  143. tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
  144. tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
  145. tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
  146. tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
  147. tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
  148. tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
  149. tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
  150. tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
  151. tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
  152. tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
  153. tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
  154. tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
  155. tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
  156. tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
  157. tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
  158. tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
  159. tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
  160. tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
  161. tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
  162. tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
  163. tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
  164. tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
  165. tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
  166. tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
  167. tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
  168. tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
  169. tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
  170. tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
  171. tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
  172. tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
  173. tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
  174. tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
  175. tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
  176. tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
  177. tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
  178. tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
  179. tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
  180. tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
  181. tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
  182. tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
  183. tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
  184. tools/bolt.diy/app/components/header/Header.tsx +42 -0
  185. tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
  186. tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
  187. tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
  188. tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
  189. tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
  190. tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
  191. tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
  192. tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
  193. tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
  194. tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
  195. tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
  196. tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
  197. tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
  198. tools/bolt.diy/app/components/txt +1 -0
  199. tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
  200. tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
  201. tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
  202. tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
  203. tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
  204. tools/bolt.diy/app/components/ui/Button.tsx +46 -0
  205. tools/bolt.diy/app/components/ui/Card.tsx +55 -0
  206. tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
  207. tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
  208. tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
  209. tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
  210. tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
  211. tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
  212. tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
  213. tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
  214. tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
  215. tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
  216. tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
  217. tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
  218. tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
  219. tools/bolt.diy/app/components/ui/Input.tsx +22 -0
  220. tools/bolt.diy/app/components/ui/Label.tsx +20 -0
  221. tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
  222. tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
  223. tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
  224. tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
  225. tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
  226. tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
  227. tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
  228. tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
  229. tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
  230. tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
  231. tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
  232. tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
  233. tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
  234. tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
  235. tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
  236. tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
  237. tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
  238. tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
  239. tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
  240. tools/bolt.diy/app/components/ui/index.ts +38 -0
  241. tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
  242. tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
  243. tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
  244. tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
  245. tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
  246. tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
  247. tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
  248. tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
  249. tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
  250. tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
  251. tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
  252. tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
  253. tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
  254. tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
  255. tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
  256. tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
  257. tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
  258. tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
  259. tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
  260. tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
  261. tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
  262. tools/bolt.diy/app/entry.client.tsx +7 -0
  263. tools/bolt.diy/app/entry.server.tsx +80 -0
  264. tools/bolt.diy/app/root.tsx +156 -0
  265. tools/bolt.diy/app/routes/_index.tsx +175 -0
  266. tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
  267. tools/bolt.diy/app/routes/api.chat.ts +463 -0
  268. tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
  269. tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
  270. tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
  271. tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
  272. tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
  273. tools/bolt.diy/app/routes/api.git-info.ts +69 -0
  274. tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
  275. tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
  276. tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
  277. tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
  278. tools/bolt.diy/app/routes/api.github-template.ts +242 -0
  279. tools/bolt.diy/app/routes/api.github-user.ts +287 -0
  280. tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
  281. tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
  282. tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
  283. tools/bolt.diy/app/routes/api.health.ts +8 -0
  284. tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
  285. tools/bolt.diy/app/routes/api.mandate.ts +351 -0
  286. tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
  287. tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
  288. tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
  289. tools/bolt.diy/app/routes/api.models.ts +90 -0
  290. tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
  291. tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
  292. tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
  293. tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
  294. tools/bolt.diy/app/routes/api.supabase.ts +56 -0
  295. tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
  296. tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
  297. tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
  298. tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
  299. tools/bolt.diy/app/routes/api.update.ts +21 -0
  300. tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
  301. tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
  302. tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
  303. tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
  304. tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
  305. tools/bolt.diy/app/routes/git.tsx +25 -0
  306. tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
  307. tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
  308. tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
  309. tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
  310. tools/bolt.diy/app/styles/animations.scss +49 -0
  311. tools/bolt.diy/app/styles/components/code.scss +9 -0
  312. tools/bolt.diy/app/styles/components/editor.scss +135 -0
  313. tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
  314. tools/bolt.diy/app/styles/components/terminal.scss +3 -0
  315. tools/bolt.diy/app/styles/components/toast.scss +23 -0
  316. tools/bolt.diy/app/styles/diff-view.css +72 -0
  317. tools/bolt.diy/app/styles/index.scss +73 -0
  318. tools/bolt.diy/app/styles/variables.scss +255 -0
  319. tools/bolt.diy/app/styles/z-index.scss +37 -0
  320. tools/bolt.diy/app/types/GitHub.ts +182 -0
  321. tools/bolt.diy/app/types/GitLab.ts +103 -0
  322. tools/bolt.diy/app/types/actions.ts +85 -0
  323. tools/bolt.diy/app/types/artifact.ts +5 -0
  324. tools/bolt.diy/app/types/context.ts +26 -0
  325. tools/bolt.diy/app/types/design-scheme.ts +93 -0
  326. tools/bolt.diy/app/types/global.d.ts +13 -0
  327. tools/bolt.diy/app/types/mandate.ts +333 -0
  328. tools/bolt.diy/app/types/model.ts +25 -0
  329. tools/bolt.diy/app/types/netlify.ts +94 -0
  330. tools/bolt.diy/app/types/supabase.ts +54 -0
  331. tools/bolt.diy/app/types/template.ts +8 -0
  332. tools/bolt.diy/app/types/terminal.ts +9 -0
  333. tools/bolt.diy/app/types/theme.ts +1 -0
  334. tools/bolt.diy/app/types/vercel.ts +67 -0
  335. tools/bolt.diy/app/utils/buffer.ts +29 -0
  336. tools/bolt.diy/app/utils/classNames.ts +65 -0
  337. tools/bolt.diy/app/utils/constants.ts +147 -0
  338. tools/bolt.diy/app/utils/debounce.ts +13 -0
  339. tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
  340. tools/bolt.diy/app/utils/diff.spec.ts +11 -0
  341. tools/bolt.diy/app/utils/diff.ts +117 -0
  342. tools/bolt.diy/app/utils/easings.ts +3 -0
  343. tools/bolt.diy/app/utils/fileLocks.ts +96 -0
  344. tools/bolt.diy/app/utils/fileUtils.ts +121 -0
  345. tools/bolt.diy/app/utils/folderImport.ts +73 -0
  346. tools/bolt.diy/app/utils/formatSize.ts +12 -0
  347. tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
  348. tools/bolt.diy/app/utils/githubStats.ts +9 -0
  349. tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
  350. tools/bolt.diy/app/utils/logger.ts +162 -0
  351. tools/bolt.diy/app/utils/markdown.ts +155 -0
  352. tools/bolt.diy/app/utils/mobile.ts +4 -0
  353. tools/bolt.diy/app/utils/os.ts +4 -0
  354. tools/bolt.diy/app/utils/path.ts +19 -0
  355. tools/bolt.diy/app/utils/projectCommands.ts +197 -0
  356. tools/bolt.diy/app/utils/promises.ts +19 -0
  357. tools/bolt.diy/app/utils/react.ts +6 -0
  358. tools/bolt.diy/app/utils/sampler.ts +49 -0
  359. tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
  360. tools/bolt.diy/app/utils/shell.ts +384 -0
  361. tools/bolt.diy/app/utils/stacktrace.ts +27 -0
  362. tools/bolt.diy/app/utils/stripIndent.ts +23 -0
  363. tools/bolt.diy/app/utils/terminal.ts +11 -0
  364. tools/bolt.diy/app/utils/unreachable.ts +3 -0
  365. tools/bolt.diy/app/vite-env.d.ts +2 -0
  366. tools/bolt.diy/assets/entitlements.mac.plist +25 -0
  367. tools/bolt.diy/assets/icons/icon.icns +0 -0
  368. tools/bolt.diy/assets/icons/icon.ico +0 -0
  369. tools/bolt.diy/assets/icons/icon.png +0 -0
  370. tools/bolt.diy/bindings.js +78 -0
  371. tools/bolt.diy/bindings.sh +33 -0
  372. tools/bolt.diy/docker-compose.yaml +145 -0
  373. tools/bolt.diy/electron/main/index.ts +201 -0
  374. tools/bolt.diy/electron/main/tsconfig.json +30 -0
  375. tools/bolt.diy/electron/main/ui/menu.ts +29 -0
  376. tools/bolt.diy/electron/main/ui/window.ts +54 -0
  377. tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
  378. tools/bolt.diy/electron/main/utils/constants.ts +4 -0
  379. tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
  380. tools/bolt.diy/electron/main/utils/reload.ts +35 -0
  381. tools/bolt.diy/electron/main/utils/serve.ts +71 -0
  382. tools/bolt.diy/electron/main/utils/store.ts +3 -0
  383. tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
  384. tools/bolt.diy/electron/main/vite.config.ts +44 -0
  385. tools/bolt.diy/electron/preload/index.ts +22 -0
  386. tools/bolt.diy/electron/preload/tsconfig.json +7 -0
  387. tools/bolt.diy/electron/preload/vite.config.ts +31 -0
  388. tools/bolt.diy/electron-builder.yml +64 -0
  389. tools/bolt.diy/electron-update.yml +4 -0
  390. tools/bolt.diy/eslint.config.mjs +57 -0
  391. tools/bolt.diy/functions/[[path]].ts +12 -0
  392. tools/bolt.diy/icons/angular.svg +1 -0
  393. tools/bolt.diy/icons/astro.svg +8 -0
  394. tools/bolt.diy/icons/chat.svg +1 -0
  395. tools/bolt.diy/icons/expo-brand.svg +1 -0
  396. tools/bolt.diy/icons/expo.svg +4 -0
  397. tools/bolt.diy/icons/logo-text.svg +1 -0
  398. tools/bolt.diy/icons/logo.svg +4 -0
  399. tools/bolt.diy/icons/mcp.svg +1 -0
  400. tools/bolt.diy/icons/nativescript.svg +1 -0
  401. tools/bolt.diy/icons/netlify.svg +10 -0
  402. tools/bolt.diy/icons/nextjs.svg +1 -0
  403. tools/bolt.diy/icons/nuxt.svg +1 -0
  404. tools/bolt.diy/icons/qwik.svg +1 -0
  405. tools/bolt.diy/icons/react.svg +1 -0
  406. tools/bolt.diy/icons/remix.svg +24 -0
  407. tools/bolt.diy/icons/remotion.svg +1 -0
  408. tools/bolt.diy/icons/shadcn.svg +21 -0
  409. tools/bolt.diy/icons/slidev.svg +60 -0
  410. tools/bolt.diy/icons/solidjs.svg +1 -0
  411. tools/bolt.diy/icons/stars.svg +1 -0
  412. tools/bolt.diy/icons/svelte.svg +1 -0
  413. tools/bolt.diy/icons/typescript.svg +1 -0
  414. tools/bolt.diy/icons/vite.svg +1 -0
  415. tools/bolt.diy/icons/vue.svg +1 -0
  416. tools/bolt.diy/load-context.ts +9 -0
  417. tools/bolt.diy/notarize.cjs +31 -0
  418. tools/bolt.diy/package.json +218 -0
  419. tools/bolt.diy/playwright.config.preview.ts +35 -0
  420. tools/bolt.diy/pre-start.cjs +26 -0
  421. tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
  422. tools/bolt.diy/public/apple-touch-icon.png +0 -0
  423. tools/bolt.diy/public/favicon.ico +0 -0
  424. tools/bolt.diy/public/favicon.svg +4 -0
  425. tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
  426. tools/bolt.diy/public/icons/Anthropic.svg +4 -0
  427. tools/bolt.diy/public/icons/Cohere.svg +4 -0
  428. tools/bolt.diy/public/icons/Deepseek.svg +5 -0
  429. tools/bolt.diy/public/icons/Default.svg +4 -0
  430. tools/bolt.diy/public/icons/Google.svg +4 -0
  431. tools/bolt.diy/public/icons/Groq.svg +4 -0
  432. tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
  433. tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
  434. tools/bolt.diy/public/icons/LMStudio.svg +5 -0
  435. tools/bolt.diy/public/icons/Mistral.svg +4 -0
  436. tools/bolt.diy/public/icons/Ollama.svg +4 -0
  437. tools/bolt.diy/public/icons/OpenAI.svg +4 -0
  438. tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
  439. tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
  440. tools/bolt.diy/public/icons/Perplexity.svg +4 -0
  441. tools/bolt.diy/public/icons/Together.svg +4 -0
  442. tools/bolt.diy/public/icons/xAI.svg +5 -0
  443. tools/bolt.diy/public/inspector-script.js +292 -0
  444. tools/bolt.diy/public/logo-dark-styled.png +0 -0
  445. tools/bolt.diy/public/logo-dark.png +0 -0
  446. tools/bolt.diy/public/logo-light-styled.png +0 -0
  447. tools/bolt.diy/public/logo-light.png +0 -0
  448. tools/bolt.diy/public/logo.svg +15 -0
  449. tools/bolt.diy/public/social_preview_index.jpg +0 -0
  450. tools/bolt.diy/scripts/clean.js +45 -0
  451. tools/bolt.diy/scripts/electron-dev.mjs +181 -0
  452. tools/bolt.diy/scripts/setup-env.sh +41 -0
  453. tools/bolt.diy/scripts/update-imports.sh +7 -0
  454. tools/bolt.diy/scripts/update.sh +52 -0
  455. tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
  456. tools/bolt.diy/services/execution-governor/config.ts +42 -0
  457. tools/bolt.diy/services/execution-governor/index.ts +683 -0
  458. tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
  459. tools/bolt.diy/services/execution-governor/package.json +31 -0
  460. tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
  461. tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
  462. tools/bolt.diy/services/execution-governor/types.ts +145 -0
  463. tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
  464. tools/bolt.diy/services/headless-executor/executor.ts +210 -0
  465. tools/bolt.diy/services/headless-executor/index.ts +323 -0
  466. tools/bolt.diy/services/headless-executor/package.json +27 -0
  467. tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
  468. tools/bolt.diy/services/headless-executor/types.ts +38 -0
  469. tools/bolt.diy/test-workflows.sh +240 -0
  470. tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
  471. tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
  472. tools/bolt.diy/tests/mandates/complex.json +53 -0
  473. tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
  474. tools/bolt.diy/tests/mandates/simple.json +35 -0
  475. tools/bolt.diy/tsconfig.json +37 -0
  476. tools/bolt.diy/types/istextorbinary.d.ts +15 -0
  477. tools/bolt.diy/uno.config.ts +279 -0
  478. tools/bolt.diy/vite-electron.config.ts +76 -0
  479. tools/bolt.diy/vite.config.ts +112 -0
  480. tools/bolt.diy/worker-configuration.d.ts +22 -0
  481. tools/bolt.diy/wrangler.toml +6 -0
  482. tools/code_generator.py +461 -0
  483. tools/file_operations.py +465 -0
  484. tools/mandate_generator.py +337 -0
  485. tools/mcpClientUtils.py +1216 -0
  486. tools/sensors.py +285 -0
  487. utils/Agent_types.py +15 -0
  488. utils/AnyToStr.py +0 -0
  489. utils/HHCS.py +277 -0
  490. utils/__init__.py +30 -0
  491. utils/agent.py +3627 -0
  492. utils/aop.py +2948 -0
  493. utils/canonical.py +143 -0
  494. utils/conversation.py +1195 -0
  495. utils/doctrine_versioning +230 -0
  496. utils/formatter.py +474 -0
  497. utils/ledger.py +311 -0
  498. utils/out_types.py +16 -0
  499. utils/rollback.py +339 -0
  500. utils/router.py +929 -0
  501. 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
+