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
utils/router.py ADDED
@@ -0,0 +1,929 @@
1
+ """
2
+ Swarm router for dynamic task routing to different swarm configurations.
3
+
4
+ Provides intelligent routing of tasks to appropriate swarm types based on
5
+ configuration or automatic selection. Supports multiple swarm architectures
6
+ including sequential, concurrent, hierarchical, and collaborative patterns.
7
+ """
8
+
9
+ import concurrent.futures
10
+ import json
11
+ import os
12
+ import traceback
13
+ from typing import Any, Callable, Dict, List, Literal, Optional, Union, get_args
14
+
15
+ from pydantic import BaseModel, Field
16
+
17
+ from swarms.prompts.multi_agent_collab_prompt import (
18
+ MULTI_AGENT_COLLAB_PROMPT_TWO,
19
+ )
20
+ from swarms.structs.agent import Agent
21
+ from swarms.structs.agent_rearrange import AgentRearrange
22
+ from swarms.structs.batched_grid_workflow import BatchedGridWorkflow
23
+ from swarms.structs.concurrent_workflow import ConcurrentWorkflow
24
+ from swarms.structs.council_as_judge import CouncilAsAJudge
25
+ # DebateWithJudge may not be available - make optional
26
+ try:
27
+ from swarms.structs.debate_with_judge import DebateWithJudge
28
+ except ImportError:
29
+ DebateWithJudge = None # Will be handled in factory
30
+ from swarms.structs.groupchat import GroupChat
31
+ from swarms.structs.heavy_swarm import HeavySwarm
32
+ from swarms.structs.hiearchical_swarm import HierarchicalSwarm
33
+ from swarms.structs.interactive_groupchat import InteractiveGroupChat
34
+ from swarms.structs.ma_utils import list_all_agents
35
+ from swarms.structs.majority_voting import MajorityVoting
36
+ from swarms.structs.malt import MALT
37
+ from swarms.structs.mixture_of_agents import MixtureOfAgents
38
+ from swarms.structs.multi_agent_router import MultiAgentRouter
39
+ from swarms.structs.sequential_workflow import SequentialWorkflow
40
+ from swarms.telemetry.log_executions import log_execution
41
+ from swarms.utils.generate_keys import generate_api_key
42
+ from swarms.utils.loguru_logger import initialize_logger
43
+ from swarms.utils.output_types import OutputType
44
+ # LLMCouncil may not be available - make optional
45
+ try:
46
+ from swarms.structs.llm_council import LLMCouncil
47
+ except ImportError:
48
+ LLMCouncil = None # Will be handled in factory
49
+ from swarms.structs.round_robin import RoundRobinSwarm
50
+
51
+ logger = initialize_logger(log_folder="swarm_router")
52
+
53
+ SwarmType = Literal[
54
+ "AgentRearrange",
55
+ "MixtureOfAgents",
56
+ "SequentialWorkflow",
57
+ "ConcurrentWorkflow",
58
+ "GroupChat",
59
+ "MultiAgentRouter",
60
+ "AutoSwarmBuilder",
61
+ "HierarchicalSwarm",
62
+ "auto",
63
+ "MajorityVoting",
64
+ "MALT",
65
+ "CouncilAsAJudge",
66
+ "InteractiveGroupChat",
67
+ "HeavySwarm",
68
+ "BatchedGridWorkflow",
69
+ "LLMCouncil",
70
+ "DebateWithJudge",
71
+ "RoundRobin",
72
+ ]
73
+
74
+
75
+ class Document(BaseModel):
76
+ file_path: str
77
+ data: str
78
+
79
+
80
+ class SwarmRouterConfig(BaseModel):
81
+ """Configuration model for SwarmRouter instances.
82
+
83
+ Attributes:
84
+ name: Identifier for the SwarmRouter instance.
85
+ description: Purpose description of the SwarmRouter.
86
+ swarm_type: Type of swarm to use.
87
+ rearrange_flow: Optional flow configuration string.
88
+ rules: Optional rules to inject into every agent.
89
+ multi_agent_collab_prompt: Whether to enable collaboration prompts.
90
+ task: Task to be executed by the swarm.
91
+ """
92
+
93
+ name: str = Field(description="Name identifier for the SwarmRouter instance")
94
+ description: str = Field(description="Description of the SwarmRouter's purpose")
95
+ swarm_type: SwarmType = Field(description="Type of swarm to use")
96
+ rearrange_flow: Optional[str] = Field(description="Flow configuration string")
97
+ rules: Optional[str] = Field(description="Rules to inject into every agent")
98
+ multi_agent_collab_prompt: bool = Field(description="Whether to enable multi-agent collaboration prompts")
99
+ task: str = Field(description="The task to be executed by the swarm")
100
+
101
+ class Config:
102
+ arbitrary_types_allowed = True
103
+
104
+
105
+ class SwarmRouterRunError(Exception):
106
+ """Exception raised when task execution fails."""
107
+ pass
108
+
109
+
110
+ class SwarmRouterConfigError(Exception):
111
+ """Exception raised when router configuration is invalid."""
112
+ pass
113
+
114
+
115
+ class SwarmRouter:
116
+ """Dynamic task router for multiple swarm architectures.
117
+
118
+ Routes tasks to appropriate swarm types based on configuration or
119
+ automatic selection. Supports sequential, concurrent, hierarchical,
120
+ and collaborative swarm patterns with comprehensive configuration options.
121
+
122
+ Attributes:
123
+ name: Router identifier name.
124
+ description: Purpose description.
125
+ swarm_type: Type of swarm to instantiate.
126
+ agents: List of agents or callables for swarm execution.
127
+ max_loops: Maximum execution loop count.
128
+ output_type: Format for output extraction.
129
+ """
130
+
131
+ def __init__(
132
+ self,
133
+ id: str = generate_api_key(prefix="swarm-router"),
134
+ name: str = "swarm-router",
135
+ description: str = "Routes your task to the desired swarm",
136
+ max_loops: int = 1,
137
+ agents: List[Union[Agent, Callable]] = [],
138
+ swarm_type: SwarmType = "SequentialWorkflow",
139
+ autosave: bool = False,
140
+ rearrange_flow: str = None,
141
+ return_json: bool = False,
142
+ auto_generate_prompts: bool = False,
143
+ shared_memory_system: Any = None,
144
+ rules: str = None,
145
+ documents: List[str] = [], # A list of docs file paths
146
+ output_type: OutputType = "dict-all-except-first",
147
+ speaker_fn: callable = None,
148
+ load_agents_from_csv: bool = False,
149
+ csv_file_path: str = None,
150
+ return_entire_history: bool = True,
151
+ multi_agent_collab_prompt: bool = True,
152
+ list_all_agents: bool = False,
153
+ conversation: Any = None,
154
+ agents_config: Optional[Dict[Any, Any]] = None,
155
+ speaker_function: str = None,
156
+ heavy_swarm_loops_per_agent: int = 1,
157
+ heavy_swarm_question_agent_model_name: str = "gpt-4.1",
158
+ heavy_swarm_worker_model_name: str = "gpt-4.1",
159
+ heavy_swarm_swarm_show_output: bool = True,
160
+ telemetry_enabled: bool = False,
161
+ council_judge_model_name: str = "gpt-4o-mini", # Add missing model_name attribute
162
+ verbose: bool = False,
163
+ worker_tools: List[Callable] = None,
164
+ aggregation_strategy: str = "synthesis",
165
+ chairman_model: str = "gpt-5.1",
166
+ *args,
167
+ **kwargs,
168
+ ):
169
+ self.id = id
170
+ self.name = name
171
+ self.description = description
172
+ self.max_loops = max_loops
173
+ self.agents = agents
174
+ self.swarm_type = swarm_type
175
+ self.autosave = autosave
176
+ self.rearrange_flow = rearrange_flow
177
+ self.return_json = return_json
178
+ self.auto_generate_prompts = auto_generate_prompts
179
+ self.shared_memory_system = shared_memory_system
180
+ self.rules = rules
181
+ self.documents = documents
182
+ self.output_type = output_type
183
+ self.speaker_fn = speaker_fn
184
+ self.logs = []
185
+ self.load_agents_from_csv = load_agents_from_csv
186
+ self.csv_file_path = csv_file_path
187
+ self.return_entire_history = return_entire_history
188
+ self.multi_agent_collab_prompt = multi_agent_collab_prompt
189
+ self.list_all_agents = list_all_agents
190
+ self.conversation = conversation
191
+ self.agents_config = agents_config
192
+ self.speaker_function = speaker_function
193
+ self.heavy_swarm_loops_per_agent = heavy_swarm_loops_per_agent
194
+ self.heavy_swarm_question_agent_model_name = (
195
+ heavy_swarm_question_agent_model_name
196
+ )
197
+ self.heavy_swarm_worker_model_name = (
198
+ heavy_swarm_worker_model_name
199
+ )
200
+ self.telemetry_enabled = telemetry_enabled
201
+ self.council_judge_model_name = council_judge_model_name
202
+ self.verbose = verbose
203
+ self.worker_tools = worker_tools
204
+ self.aggregation_strategy = aggregation_strategy
205
+ self.heavy_swarm_swarm_show_output = (
206
+ heavy_swarm_swarm_show_output
207
+ )
208
+ self.chairman_model = chairman_model
209
+
210
+ # Initialize swarm factory for O(1) lookup performance
211
+ self._swarm_factory = self._initialize_swarm_factory()
212
+ self._swarm_cache: Dict[str, Any] = {}
213
+
214
+ # Reliability check
215
+ self.reliability_check()
216
+
217
+ def reliability_check(self) -> None:
218
+ """Validate swarm configuration parameters.
219
+
220
+ Performs comprehensive validation of swarm type, agents, and
221
+ configuration parameters before execution.
222
+
223
+ Raises:
224
+ SwarmRouterConfigError: If configuration is invalid.
225
+ """
226
+ try:
227
+ if self.verbose:
228
+ logger.info(
229
+ f"[SwarmRouter Reliability Check] Initializing SwarmRouter '{self.name}'. "
230
+ "Validating required parameters for robust operation.\n"
231
+ "For detailed documentation on SwarmRouter configuration, usage, and available swarm types, "
232
+ "please visit: https://docs.swarms.world/en/latest/swarms/structs/swarm_router/"
233
+ )
234
+
235
+ # Check swarm type first since it affects other validations
236
+ if self.swarm_type is None:
237
+ raise SwarmRouterConfigError(
238
+ "SwarmRouter: Swarm type cannot be 'none'. Check the docs for all the swarm types available. https://docs.swarms.world/en/latest/swarms/structs/swarm_router/"
239
+ )
240
+
241
+ # Validate swarm type is a valid string
242
+ valid_swarm_types = get_args(SwarmType)
243
+
244
+ if not isinstance(self.swarm_type, str):
245
+ raise SwarmRouterConfigError(
246
+ f"SwarmRouter: swarm_type must be a string, not {type(self.swarm_type).__name__}. "
247
+ f"Valid types are: {', '.join(valid_swarm_types)}. "
248
+ "Use swarm_type='SequentialWorkflow' (string), NOT SwarmType.SequentialWorkflow. "
249
+ "See https://docs.swarms.world/en/latest/swarms/structs/swarm_router/"
250
+ )
251
+
252
+ if self.swarm_type not in valid_swarm_types:
253
+ raise SwarmRouterConfigError(
254
+ f"SwarmRouter: Invalid swarm_type '{self.swarm_type}'. "
255
+ f"Valid types are: {', '.join(valid_swarm_types)}. "
256
+ "See https://docs.swarms.world/en/latest/swarms/structs/swarm_router/"
257
+ )
258
+
259
+ if (
260
+ self.swarm_type == "AgentRearrange"
261
+ and self.rearrange_flow is None
262
+ ):
263
+ raise SwarmRouterConfigError(
264
+ "SwarmRouter: rearrange_flow cannot be 'none' when using AgentRearrange. Check the SwarmRouter docs to learn of required parameters. https://docs.swarms.world/en/latest/swarms/structs/agent_rearrange/"
265
+ )
266
+
267
+ # Validate max_loops
268
+ if self.max_loops == 0:
269
+ raise SwarmRouterConfigError(
270
+ "SwarmRouter: max_loops cannot be 0. Check the docs for all the max_loops available. https://docs.swarms.world/en/latest/swarms/structs/swarm_router/"
271
+ )
272
+
273
+ self.setup()
274
+
275
+ if self.telemetry_enabled:
276
+ self.agent_config = self.agent_config()
277
+
278
+ except SwarmRouterConfigError as e:
279
+ logger.error(
280
+ f"SwarmRouterConfigError: {str(e)} Full Traceback: {traceback.format_exc()}"
281
+ )
282
+ raise e
283
+
284
+ def setup(self):
285
+ if self.auto_generate_prompts is True:
286
+ self.activate_ape()
287
+
288
+ # Handle shared memory
289
+ if self.shared_memory_system is not None:
290
+ self.activate_shared_memory()
291
+
292
+ # Handle rules
293
+ if self.rules is not None:
294
+ self.handle_rules()
295
+
296
+ if self.multi_agent_collab_prompt is True:
297
+ self.update_system_prompt_for_agent_in_swarm()
298
+
299
+ if self.list_all_agents is True:
300
+ self.list_agents_to_eachother()
301
+
302
+ def fetch_message_history_as_string(self):
303
+ try:
304
+ return (
305
+ self.swarm.conversation.return_all_except_first_string()
306
+ )
307
+ except Exception as e:
308
+ logger.error(
309
+ f"Error fetching message history as string: {str(e)}"
310
+ )
311
+ return None
312
+
313
+ def activate_shared_memory(self):
314
+ logger.info("Activating shared memory with all agents ")
315
+
316
+ for agent in self.agents:
317
+ agent.long_term_memory = self.shared_memory_system
318
+
319
+ logger.info("All agents now have the same memory system")
320
+
321
+ def handle_rules(self):
322
+ logger.info("Injecting rules to every agent!")
323
+
324
+ for agent in self.agents:
325
+ agent.system_prompt += f"### Swarm Rules ### {self.rules}"
326
+
327
+ logger.info("Finished injecting rules")
328
+
329
+ def activate_ape(self):
330
+ """Activate automatic prompt engineering for agents that support it"""
331
+ try:
332
+ logger.info("Activating automatic prompt engineering...")
333
+ activated_count = 0
334
+ for agent in self.agents:
335
+ if hasattr(agent, "auto_generate_prompt"):
336
+ agent.auto_generate_prompt = (
337
+ self.auto_generate_prompts
338
+ )
339
+ activated_count += 1
340
+ logger.debug(
341
+ f"Activated APE for agent: {agent.name if hasattr(agent, 'name') else 'unnamed'}"
342
+ )
343
+
344
+ logger.info(
345
+ f"Successfully activated APE for {activated_count} agents"
346
+ )
347
+
348
+ except Exception as e:
349
+ error_msg = f"Error activating automatic prompt engineering: {str(e)}"
350
+ logger.error(
351
+ f"Error activating automatic prompt engineering in SwarmRouter: {str(e)}"
352
+ )
353
+ raise RuntimeError(error_msg) from e
354
+
355
+ def _initialize_swarm_factory(self) -> Dict[str, Callable]:
356
+ """
357
+ Initialize the swarm factory with O(1) lookup performance.
358
+
359
+ Returns:
360
+ Dict[str, Callable]: Dictionary mapping swarm types to their factory functions.
361
+ """
362
+ factory = {
363
+ "HeavySwarm": self._create_heavy_swarm,
364
+ "AgentRearrange": self._create_agent_rearrange,
365
+ "MALT": self._create_malt,
366
+ "CouncilAsAJudge": self._create_council_as_judge,
367
+ "InteractiveGroupChat": self._create_interactive_group_chat,
368
+ "HierarchicalSwarm": self._create_hierarchical_swarm,
369
+ "MixtureOfAgents": self._create_mixture_of_agents,
370
+ "MajorityVoting": self._create_majority_voting,
371
+ "GroupChat": self._create_group_chat,
372
+ "MultiAgentRouter": self._create_multi_agent_router,
373
+ "SequentialWorkflow": self._create_sequential_workflow,
374
+ "ConcurrentWorkflow": self._create_concurrent_workflow,
375
+ "BatchedGridWorkflow": self._create_batched_grid_workflow,
376
+ "RoundRobin": self._create_round_robin_swarm,
377
+ }
378
+ # Conditionally add optional swarm types if available
379
+ if LLMCouncil is not None:
380
+ factory["LLMCouncil"] = self._create_llm_council
381
+ if DebateWithJudge is not None:
382
+ factory["DebateWithJudge"] = self._create_debate_with_judge
383
+ return factory
384
+
385
+ def _create_heavy_swarm(self, *args: Any, **kwargs: Any) -> HeavySwarm:
386
+ """Create HeavySwarm instance."""
387
+ return HeavySwarm(
388
+ name=self.name,
389
+ description=self.description,
390
+ output_type=self.output_type,
391
+ loops_per_agent=self.heavy_swarm_loops_per_agent,
392
+ question_agent_model_name=self.heavy_swarm_question_agent_model_name,
393
+ worker_model_name=self.heavy_swarm_worker_model_name,
394
+ agent_prints_on=self.heavy_swarm_swarm_show_output,
395
+ worker_tools=self.worker_tools,
396
+ aggregation_strategy=self.aggregation_strategy,
397
+ show_dashboard=False,
398
+ )
399
+
400
+ def _create_llm_council(self, *args: Any, **kwargs: Any):
401
+ """Create LLMCouncil instance."""
402
+ if LLMCouncil is None:
403
+ raise ValueError(
404
+ "LLMCouncil is not available. Please install the required swarms package version."
405
+ )
406
+ return LLMCouncil(
407
+ name=self.name,
408
+ description=self.description,
409
+ output_type=self.output_type,
410
+ verbose=self.verbose,
411
+ chairman_model=self.chairman_model,
412
+ )
413
+
414
+ def _create_debate_with_judge(self, *args: Any, **kwargs: Any):
415
+ """Create DebateWithJudge instance."""
416
+ if DebateWithJudge is None:
417
+ raise ValueError(
418
+ "DebateWithJudge is not available. Please install the required swarms package version."
419
+ )
420
+ return DebateWithJudge(
421
+ pro_agent=self.agents[0],
422
+ con_agent=self.agents[1],
423
+ judge_agent=self.agents[2],
424
+ max_rounds=self.max_loops,
425
+ output_type=self.output_type,
426
+ verbose=self.verbose,
427
+ )
428
+
429
+ def _create_agent_rearrange(self, *args: Any, **kwargs: Any) -> AgentRearrange:
430
+ """Create AgentRearrange instance."""
431
+ return AgentRearrange(
432
+ name=self.name,
433
+ description=self.description,
434
+ agents=self.agents,
435
+ max_loops=self.max_loops,
436
+ flow=self.rearrange_flow,
437
+ output_type=self.output_type,
438
+ *args,
439
+ **kwargs,
440
+ )
441
+
442
+ def _create_batched_grid_workflow(self, *args: Any, **kwargs: Any) -> BatchedGridWorkflow:
443
+ """Create BatchedGridWorkflow instance."""
444
+ return BatchedGridWorkflow(
445
+ name=self.name,
446
+ description=self.description,
447
+ agents=self.agents,
448
+ max_loops=self.max_loops,
449
+ )
450
+
451
+ def _create_malt(self, *args: Any, **kwargs: Any) -> MALT:
452
+ """Create MALT instance."""
453
+ return MALT(
454
+ name=self.name,
455
+ description=self.description,
456
+ max_loops=self.max_loops,
457
+ return_dict=True,
458
+ preset_agents=True,
459
+ )
460
+
461
+ def _create_council_as_judge(self, *args: Any, **kwargs: Any) -> CouncilAsAJudge:
462
+ """Create CouncilAsAJudge instance."""
463
+ return CouncilAsAJudge(
464
+ name=self.name,
465
+ description=self.description,
466
+ model_name=self.council_judge_model_name,
467
+ output_type=self.output_type,
468
+ )
469
+
470
+ def _create_interactive_group_chat(self, *args: Any, **kwargs: Any) -> InteractiveGroupChat:
471
+ """Create InteractiveGroupChat instance."""
472
+ return InteractiveGroupChat(
473
+ name=self.name,
474
+ description=self.description,
475
+ agents=self.agents,
476
+ max_loops=self.max_loops,
477
+ output_type=self.output_type,
478
+ speaker_function=self.speaker_function,
479
+ )
480
+
481
+ def _create_hierarchical_swarm(self, *args: Any, **kwargs: Any) -> HierarchicalSwarm:
482
+ """Create HierarchicalSwarm instance."""
483
+ return HierarchicalSwarm(
484
+ name=self.name,
485
+ description=self.description,
486
+ agents=self.agents,
487
+ max_loops=self.max_loops,
488
+ output_type=self.output_type,
489
+ *args,
490
+ **kwargs,
491
+ )
492
+
493
+ def _create_mixture_of_agents(self, *args: Any, **kwargs: Any) -> MixtureOfAgents:
494
+ """Create MixtureOfAgents instance."""
495
+ return MixtureOfAgents(
496
+ name=self.name,
497
+ description=self.description,
498
+ agents=self.agents,
499
+ aggregator_agent=self.agents[-1],
500
+ layers=self.max_loops,
501
+ output_type=self.output_type,
502
+ *args,
503
+ **kwargs,
504
+ )
505
+
506
+ def _create_majority_voting(self, *args: Any, **kwargs: Any) -> MajorityVoting:
507
+ """Create MajorityVoting instance."""
508
+ return MajorityVoting(
509
+ name=self.name,
510
+ description=self.description,
511
+ agents=self.agents,
512
+ max_loops=self.max_loops,
513
+ output_type=self.output_type,
514
+ *args,
515
+ **kwargs,
516
+ )
517
+
518
+ def _create_group_chat(self, *args: Any, **kwargs: Any) -> GroupChat:
519
+ """Create GroupChat instance."""
520
+ return GroupChat(
521
+ name=self.name,
522
+ description=self.description,
523
+ agents=self.agents,
524
+ max_loops=self.max_loops,
525
+ speaker_fn=self.speaker_fn,
526
+ *args,
527
+ **kwargs,
528
+ )
529
+
530
+ def _create_multi_agent_router(self, *args: Any, **kwargs: Any) -> MultiAgentRouter:
531
+ """Create MultiAgentRouter instance."""
532
+ return MultiAgentRouter(
533
+ name=self.name,
534
+ description=self.description,
535
+ agents=self.agents,
536
+ shared_memory_system=self.shared_memory_system,
537
+ output_type=self.output_type,
538
+ )
539
+
540
+ def _create_sequential_workflow(self, *args: Any, **kwargs: Any) -> SequentialWorkflow:
541
+ """Create SequentialWorkflow instance."""
542
+ return SequentialWorkflow(
543
+ name=self.name,
544
+ description=self.description,
545
+ agents=self.agents,
546
+ max_loops=self.max_loops,
547
+ shared_memory_system=self.shared_memory_system,
548
+ output_type=self.output_type,
549
+ *args,
550
+ **kwargs,
551
+ )
552
+
553
+ def _create_concurrent_workflow(self, *args: Any, **kwargs: Any) -> ConcurrentWorkflow:
554
+ """Create ConcurrentWorkflow instance."""
555
+ return ConcurrentWorkflow(
556
+ name=self.name,
557
+ description=self.description,
558
+ agents=self.agents,
559
+ max_loops=self.max_loops,
560
+ output_type=self.output_type,
561
+ *args,
562
+ **kwargs,
563
+ )
564
+
565
+ def _create_round_robin_swarm(self, *args: Any, **kwargs: Any) -> RoundRobinSwarm:
566
+ """Create RoundRobinSwarm instance."""
567
+ return RoundRobinSwarm(
568
+ name=self.name,
569
+ description=self.description,
570
+ agents=self.agents,
571
+ max_loops=self.max_loops,
572
+ verbose=self.verbose,
573
+ return_json_on=self.return_json,
574
+ *args,
575
+ **kwargs,
576
+ )
577
+
578
+ def _create_swarm(self, task: str = None, *args, **kwargs):
579
+ """
580
+ Dynamically create and return the specified swarm type with O(1) lookup performance.
581
+ Uses factory pattern with caching for optimal performance.
582
+
583
+ Args:
584
+ task (str, optional): The task to be executed by the swarm. Defaults to None.
585
+ *args: Variable length argument list.
586
+ **kwargs: Arbitrary keyword arguments.
587
+
588
+ Returns:
589
+ Union[AgentRearrange, MixtureOfAgents, SequentialWorkflow, ConcurrentWorkflow]:
590
+ The instantiated swarm object.
591
+
592
+ Raises:
593
+ ValueError: If an invalid swarm type is provided.
594
+ """
595
+
596
+ # Check cache first for better performance
597
+ cache_key = (
598
+ f"{self.swarm_type}_{hash(str(args) + str(kwargs))}"
599
+ )
600
+ if cache_key in self._swarm_cache:
601
+ logger.debug(f"Using cached swarm: {self.swarm_type}")
602
+ return self._swarm_cache[cache_key]
603
+
604
+ # Use factory pattern for O(1) lookup
605
+ factory_func = self._swarm_factory.get(self.swarm_type)
606
+ if factory_func is None:
607
+ valid_types = list(self._swarm_factory.keys())
608
+ raise ValueError(
609
+ f"Invalid swarm type: {self.swarm_type}. "
610
+ f"Valid types are: {', '.join(valid_types)}"
611
+ )
612
+
613
+ # Create the swarm using the factory function
614
+ try:
615
+ swarm = factory_func(*args, **kwargs)
616
+
617
+ # Cache the created swarm for future use
618
+ self._swarm_cache[cache_key] = swarm
619
+
620
+ logger.info(
621
+ f"Successfully created swarm: {self.swarm_type}"
622
+ )
623
+ return swarm
624
+
625
+ except Exception as e:
626
+ logger.error(
627
+ f"Failed to create swarm {self.swarm_type}: {str(e)}"
628
+ )
629
+ raise RuntimeError(
630
+ f"Failed to create swarm {self.swarm_type}: {str(e)}"
631
+ ) from e
632
+
633
+ def update_system_prompt_for_agent_in_swarm(self):
634
+ # Use list comprehension for faster iteration
635
+ for agent in self.agents:
636
+ if agent.system_prompt is None:
637
+ agent.system_prompt = ""
638
+ agent.system_prompt += MULTI_AGENT_COLLAB_PROMPT_TWO
639
+
640
+ def agent_config(self):
641
+ agent_config = {}
642
+ for agent in self.agents:
643
+ agent_config[agent.agent_name] = agent.to_dict()
644
+
645
+ return agent_config
646
+
647
+ def list_agents_to_eachother(self):
648
+ if self.swarm_type == "SequentialWorkflow":
649
+ self.conversation = (
650
+ self.swarm.agent_rearrange.conversation
651
+ )
652
+ else:
653
+ self.conversation = self.swarm.conversation
654
+
655
+ if self.list_all_agents is True:
656
+ list_all_agents(
657
+ agents=self.agents,
658
+ conversation=self.swarm.conversation,
659
+ name=self.name,
660
+ description=self.description,
661
+ add_collaboration_prompt=True,
662
+ add_to_conversation=True,
663
+ )
664
+
665
+ def _run(
666
+ self,
667
+ task: Optional[str] = None,
668
+ tasks: Optional[List[str]] = None,
669
+ img: Optional[str] = None,
670
+ *args,
671
+ **kwargs,
672
+ ) -> Any:
673
+ """
674
+ Dynamically run the specified task on the selected or matched swarm type.
675
+
676
+ Args:
677
+ task (str): The task to be executed by the swarm.
678
+ *args: Variable length argument list.
679
+ **kwargs: Arbitrary keyword arguments.
680
+
681
+ Returns:
682
+ Any: The result of the swarm's execution.
683
+
684
+ Raises:
685
+ Exception: If an error occurs during task execution.
686
+ """
687
+ self.swarm = self._create_swarm(task, *args, **kwargs)
688
+
689
+ log_execution(
690
+ swarm_id=self.id,
691
+ status="start",
692
+ swarm_config=self.to_dict(),
693
+ swarm_architecture="swarm_router",
694
+ enabled_on=self.telemetry_enabled,
695
+ )
696
+
697
+ args = {}
698
+
699
+ if tasks is not None:
700
+ args["tasks"] = tasks
701
+ else:
702
+ args["task"] = task
703
+
704
+ if img is not None:
705
+ args["img"] = img
706
+
707
+ try:
708
+ if self.swarm_type == "BatchedGridWorkflow":
709
+ result = self.swarm.run(**args, **kwargs)
710
+ else:
711
+ result = self.swarm.run(**args, **kwargs)
712
+
713
+ log_execution(
714
+ swarm_id=self.id,
715
+ status="completion",
716
+ swarm_config=self.to_dict(),
717
+ swarm_architecture="swarm_router",
718
+ enabled_on=self.telemetry_enabled,
719
+ )
720
+
721
+ return result
722
+ except SwarmRouterRunError as e:
723
+ logger.error(
724
+ f"\n[SwarmRouter ERROR] '{self.name}' failed to execute the task on the selected swarm.\n"
725
+ f"Reason: {str(e)}\n"
726
+ f"Traceback:\n{traceback.format_exc()}\n\n"
727
+ "Troubleshooting steps:\n"
728
+ " - Double-check your SwarmRouter configuration (swarm_type, agents, parameters).\n"
729
+ " - Ensure all individual agents are properly configured and initialized.\n"
730
+ " - Review the error message and traceback above for clues.\n\n"
731
+ "For detailed documentation on SwarmRouter configuration, usage, and available swarm types, please visit:\n"
732
+ " https://docs.swarms.world/en/latest/swarms/structs/swarm_router/\n"
733
+ )
734
+ raise e
735
+
736
+ def run(
737
+ self,
738
+ task: Optional[str] = None,
739
+ img: Optional[str] = None,
740
+ tasks: Optional[List[str]] = None,
741
+ *args,
742
+ **kwargs,
743
+ ) -> Any:
744
+ """
745
+ Execute a task on the selected swarm type with specified compute resources.
746
+
747
+ Args:
748
+ task (str): The task to be executed by the swarm.
749
+ device (str, optional): Device to run on - "cpu" or "gpu". Defaults to "cpu".
750
+ all_cores (bool, optional): Whether to use all CPU cores. Defaults to True.
751
+ all_gpus (bool, optional): Whether to use all available GPUs. Defaults to False.
752
+ *args: Variable length argument list.
753
+ **kwargs: Arbitrary keyword arguments.
754
+
755
+ Returns:
756
+ Any: The result of the swarm's execution.
757
+
758
+ Raises:
759
+ Exception: If an error occurs during task execution.
760
+ """
761
+ try:
762
+ return self._run(
763
+ task=task,
764
+ img=img,
765
+ tasks=tasks,
766
+ *args,
767
+ **kwargs,
768
+ )
769
+ except SwarmRouterRunError as e:
770
+ logger.error(
771
+ f"\n[SwarmRouter ERROR] '{self.name}' failed to execute the task on the selected swarm.\n"
772
+ f"Reason: {str(e)}\n"
773
+ f"Traceback:\n{traceback.format_exc()}\n\n"
774
+ "Troubleshooting steps:\n"
775
+ " - Double-check your SwarmRouter configuration (swarm_type, agents, parameters).\n"
776
+ " - Ensure all individual agents are properly configured and initialized.\n"
777
+ " - Review the error message and traceback above for clues.\n\n"
778
+ "For detailed documentation on SwarmRouter configuration, usage, and available swarm types, please visit:\n"
779
+ " https://docs.swarms.world/en/latest/swarms/structs/swarm_router/\n"
780
+ )
781
+ raise e
782
+
783
+ def __call__(
784
+ self,
785
+ task: str,
786
+ img: Optional[str] = None,
787
+ imgs: Optional[List[str]] = None,
788
+ *args,
789
+ **kwargs,
790
+ ) -> Any:
791
+ """
792
+ Make the SwarmRouter instance callable.
793
+
794
+ Args:
795
+ task (str): The task to be executed by the swarm.
796
+ *args: Variable length argument list.
797
+ **kwargs: Arbitrary keyword arguments.
798
+
799
+ Returns:
800
+ Any: The result of the swarm's execution.
801
+ """
802
+ return self.run(
803
+ task=task, img=img, imgs=imgs, *args, **kwargs
804
+ )
805
+
806
+ def batch_run(
807
+ self,
808
+ tasks: List[str],
809
+ img: Optional[str] = None,
810
+ imgs: Optional[List[str]] = None,
811
+ *args,
812
+ **kwargs,
813
+ ) -> List[Any]:
814
+ """
815
+ Execute a batch of tasks on the selected or matched swarm type.
816
+
817
+ Args:
818
+ tasks (List[str]): A list of tasks to be executed by the swarm.
819
+ *args: Variable length argument list.
820
+ **kwargs: Arbitrary keyword arguments.
821
+
822
+ Returns:
823
+ List[Any]: A list of results from the swarm's execution.
824
+
825
+ Raises:
826
+ Exception: If an error occurs during task execution.
827
+ """
828
+ results = []
829
+ for task in tasks:
830
+ try:
831
+ result = self.run(
832
+ task, img=img, imgs=imgs, *args, **kwargs
833
+ )
834
+ results.append(result)
835
+ except Exception as e:
836
+ raise RuntimeError(
837
+ f"SwarmRouter: Error executing batch task on swarm: {str(e)} Traceback: {traceback.format_exc()}"
838
+ )
839
+ return results
840
+
841
+ def concurrent_run(
842
+ self,
843
+ task: str,
844
+ img: Optional[str] = None,
845
+ imgs: Optional[List[str]] = None,
846
+ *args,
847
+ **kwargs,
848
+ ) -> Any:
849
+ """
850
+ Execute a task on the selected or matched swarm type concurrently.
851
+
852
+ Args:
853
+ task (str): The task to be executed by the swarm.
854
+ *args: Variable length argument list.
855
+ **kwargs: Arbitrary keyword arguments.
856
+
857
+ Returns:
858
+ Any: The result of the swarm's execution.
859
+
860
+ Raises:
861
+ Exception: If an error occurs during task execution.
862
+ """
863
+
864
+ with concurrent.futures.ThreadPoolExecutor(
865
+ max_workers=os.cpu_count()
866
+ ) as executor:
867
+ future = executor.submit(
868
+ self.run, task, img=img, imgs=imgs, *args, **kwargs
869
+ )
870
+ result = future.result()
871
+ return result
872
+
873
+ def _serialize_callable(
874
+ self, attr_value: Callable
875
+ ) -> Dict[str, Any]:
876
+ """
877
+ Serializes callable attributes by extracting their name and docstring.
878
+
879
+ Args:
880
+ attr_value (Callable): The callable to serialize.
881
+
882
+ Returns:
883
+ Dict[str, Any]: Dictionary with name and docstring of the callable.
884
+ """
885
+ return {
886
+ "name": getattr(
887
+ attr_value, "__name__", type(attr_value).__name__
888
+ ),
889
+ "doc": getattr(attr_value, "__doc__", None),
890
+ }
891
+
892
+ def _serialize_attr(self, attr_name: str, attr_value: Any) -> Any:
893
+ """
894
+ Serializes an individual attribute, handling non-serializable objects.
895
+
896
+ Args:
897
+ attr_name (str): The name of the attribute.
898
+ attr_value (Any): The value of the attribute.
899
+
900
+ Returns:
901
+ Any: The serialized value of the attribute.
902
+ """
903
+ try:
904
+ if callable(attr_value):
905
+ return self._serialize_callable(attr_value)
906
+ elif hasattr(attr_value, "to_dict"):
907
+ return (
908
+ attr_value.to_dict()
909
+ ) # Recursive serialization for nested objects
910
+ else:
911
+ json.dumps(
912
+ attr_value
913
+ ) # Attempt to serialize to catch non-serializable objects
914
+ return attr_value
915
+ except (TypeError, ValueError):
916
+ return f"<Non-serializable: {type(attr_value).__name__}>"
917
+
918
+ def to_dict(self) -> Dict[str, Any]:
919
+ """
920
+ Converts all attributes of the class, including callables, into a dictionary.
921
+ Handles non-serializable attributes by converting them or skipping them.
922
+
923
+ Returns:
924
+ Dict[str, Any]: A dictionary representation of the class attributes.
925
+ """
926
+ return {
927
+ attr_name: self._serialize_attr(attr_name, attr_value)
928
+ for attr_name, attr_value in self.__dict__.items()
929
+ }