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,298 @@
1
+ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
+ import { streamText } from '~/lib/.server/llm/stream-text';
3
+ import type { IProviderSetting, ProviderInfo } from '~/types/model';
4
+ import { generateText } from 'ai';
5
+ import { PROVIDER_LIST } from '~/utils/constants';
6
+ import { MAX_TOKENS, PROVIDER_COMPLETION_LIMITS, isReasoningModel } from '~/lib/.server/llm/constants';
7
+ import { LLMManager } from '~/lib/modules/llm/manager';
8
+ import type { ModelInfo } from '~/lib/modules/llm/types';
9
+ import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
10
+ import { createScopedLogger } from '~/utils/logger';
11
+
12
+ export async function action(args: ActionFunctionArgs) {
13
+ return llmCallAction(args);
14
+ }
15
+
16
+ async function getModelList(options: {
17
+ apiKeys?: Record<string, string>;
18
+ providerSettings?: Record<string, IProviderSetting>;
19
+ serverEnv?: Record<string, string>;
20
+ }) {
21
+ const llmManager = LLMManager.getInstance(import.meta.env);
22
+ return llmManager.updateModelList(options);
23
+ }
24
+
25
+ const logger = createScopedLogger('api.llmcall');
26
+
27
+ function getCompletionTokenLimit(modelDetails: ModelInfo): number {
28
+ // 1. If model specifies completion tokens, use that
29
+ if (modelDetails.maxCompletionTokens && modelDetails.maxCompletionTokens > 0) {
30
+ return modelDetails.maxCompletionTokens;
31
+ }
32
+
33
+ // 2. Use provider-specific default
34
+ const providerDefault = PROVIDER_COMPLETION_LIMITS[modelDetails.provider];
35
+
36
+ if (providerDefault) {
37
+ return providerDefault;
38
+ }
39
+
40
+ // 3. Final fallback to MAX_TOKENS, but cap at reasonable limit for safety
41
+ return Math.min(MAX_TOKENS, 16384);
42
+ }
43
+
44
+ function validateTokenLimits(modelDetails: ModelInfo, requestedTokens: number): { valid: boolean; error?: string } {
45
+ const modelMaxTokens = modelDetails.maxTokenAllowed || 128000;
46
+ const maxCompletionTokens = getCompletionTokenLimit(modelDetails);
47
+
48
+ // Check against model's context window
49
+ if (requestedTokens > modelMaxTokens) {
50
+ return {
51
+ valid: false,
52
+ error: `Requested tokens (${requestedTokens}) exceed model's context window (${modelMaxTokens}). Please reduce your request size.`,
53
+ };
54
+ }
55
+
56
+ // Check against completion token limits
57
+ if (requestedTokens > maxCompletionTokens) {
58
+ return {
59
+ valid: false,
60
+ error: `Requested tokens (${requestedTokens}) exceed model's completion limit (${maxCompletionTokens}). Consider using a model with higher token limits.`,
61
+ };
62
+ }
63
+
64
+ return { valid: true };
65
+ }
66
+
67
+ async function llmCallAction({ context, request }: ActionFunctionArgs) {
68
+ const { system, message, model, provider, streamOutput } = await request.json<{
69
+ system: string;
70
+ message: string;
71
+ model: string;
72
+ provider: ProviderInfo;
73
+ streamOutput?: boolean;
74
+ }>();
75
+
76
+ const { name: providerName } = provider;
77
+
78
+ // validate 'model' and 'provider' fields
79
+ if (!model || typeof model !== 'string') {
80
+ throw new Response('Invalid or missing model', {
81
+ status: 400,
82
+ statusText: 'Bad Request',
83
+ });
84
+ }
85
+
86
+ if (!providerName || typeof providerName !== 'string') {
87
+ throw new Response('Invalid or missing provider', {
88
+ status: 400,
89
+ statusText: 'Bad Request',
90
+ });
91
+ }
92
+
93
+ const cookieHeader = request.headers.get('Cookie');
94
+ const apiKeys = getApiKeysFromCookie(cookieHeader);
95
+ const providerSettings = getProviderSettingsFromCookie(cookieHeader);
96
+
97
+ if (streamOutput) {
98
+ try {
99
+ const result = await streamText({
100
+ options: {
101
+ system,
102
+ },
103
+ messages: [
104
+ {
105
+ role: 'user',
106
+ content: `${message}`,
107
+ },
108
+ ],
109
+ env: context.cloudflare?.env as any,
110
+ apiKeys,
111
+ providerSettings,
112
+ });
113
+
114
+ return new Response(result.textStream, {
115
+ status: 200,
116
+ headers: {
117
+ 'Content-Type': 'text/plain; charset=utf-8',
118
+ },
119
+ });
120
+ } catch (error: unknown) {
121
+ console.log(error);
122
+
123
+ if (error instanceof Error && error.message?.includes('API key')) {
124
+ throw new Response('Invalid or missing API key', {
125
+ status: 401,
126
+ statusText: 'Unauthorized',
127
+ });
128
+ }
129
+
130
+ // Handle token limit errors with helpful messages
131
+ if (
132
+ error instanceof Error &&
133
+ (error.message?.includes('max_tokens') ||
134
+ error.message?.includes('token') ||
135
+ error.message?.includes('exceeds') ||
136
+ error.message?.includes('maximum'))
137
+ ) {
138
+ throw new Response(
139
+ `Token limit error: ${error.message}. Try reducing your request size or using a model with higher token limits.`,
140
+ {
141
+ status: 400,
142
+ statusText: 'Token Limit Exceeded',
143
+ },
144
+ );
145
+ }
146
+
147
+ throw new Response(null, {
148
+ status: 500,
149
+ statusText: 'Internal Server Error',
150
+ });
151
+ }
152
+ } else {
153
+ try {
154
+ const models = await getModelList({ apiKeys, providerSettings, serverEnv: context.cloudflare?.env as any });
155
+ const modelDetails = models.find((m: ModelInfo) => m.name === model);
156
+
157
+ if (!modelDetails) {
158
+ throw new Error('Model not found');
159
+ }
160
+
161
+ const dynamicMaxTokens = modelDetails ? getCompletionTokenLimit(modelDetails) : Math.min(MAX_TOKENS, 16384);
162
+
163
+ // Validate token limits before making API request
164
+ const validation = validateTokenLimits(modelDetails, dynamicMaxTokens);
165
+
166
+ if (!validation.valid) {
167
+ throw new Response(validation.error, {
168
+ status: 400,
169
+ statusText: 'Token Limit Exceeded',
170
+ });
171
+ }
172
+
173
+ const providerInfo = PROVIDER_LIST.find((p) => p.name === provider.name);
174
+
175
+ if (!providerInfo) {
176
+ throw new Error('Provider not found');
177
+ }
178
+
179
+ logger.info(`Generating response Provider: ${provider.name}, Model: ${modelDetails.name}`);
180
+
181
+ // DEBUG: Log reasoning model detection
182
+ const isReasoning = isReasoningModel(modelDetails.name);
183
+ logger.info(`DEBUG: Model "${modelDetails.name}" detected as reasoning model: ${isReasoning}`);
184
+
185
+ // Use maxCompletionTokens for reasoning models (o1, GPT-5), maxTokens for traditional models
186
+ const tokenParams = isReasoning ? { maxCompletionTokens: dynamicMaxTokens } : { maxTokens: dynamicMaxTokens };
187
+
188
+ // Filter out unsupported parameters for reasoning models
189
+ const baseParams = {
190
+ system,
191
+ messages: [
192
+ {
193
+ role: 'user' as const,
194
+ content: `${message}`,
195
+ },
196
+ ],
197
+ model: providerInfo.getModelInstance({
198
+ model: modelDetails.name,
199
+ serverEnv: context.cloudflare?.env as any,
200
+ apiKeys,
201
+ providerSettings,
202
+ }),
203
+ ...tokenParams,
204
+ toolChoice: 'none' as const,
205
+ };
206
+
207
+ // For reasoning models, set temperature to 1 (required by OpenAI API)
208
+ const finalParams = isReasoning
209
+ ? { ...baseParams, temperature: 1 } // Set to 1 for reasoning models (only supported value)
210
+ : { ...baseParams, temperature: 0 };
211
+
212
+ // DEBUG: Log final parameters
213
+ logger.info(
214
+ `DEBUG: Final params for model "${modelDetails.name}":`,
215
+ JSON.stringify(
216
+ {
217
+ isReasoning,
218
+ hasTemperature: 'temperature' in finalParams,
219
+ hasMaxTokens: 'maxTokens' in finalParams,
220
+ hasMaxCompletionTokens: 'maxCompletionTokens' in finalParams,
221
+ paramKeys: Object.keys(finalParams).filter((key) => !['model', 'messages', 'system'].includes(key)),
222
+ tokenParams,
223
+ finalParams: Object.fromEntries(
224
+ Object.entries(finalParams).filter(([key]) => !['model', 'messages', 'system'].includes(key)),
225
+ ),
226
+ },
227
+ null,
228
+ 2,
229
+ ),
230
+ );
231
+
232
+ const result = await generateText(finalParams);
233
+ logger.info(`Generated response`);
234
+
235
+ return new Response(JSON.stringify(result), {
236
+ status: 200,
237
+ headers: {
238
+ 'Content-Type': 'application/json',
239
+ },
240
+ });
241
+ } catch (error: unknown) {
242
+ console.log(error);
243
+
244
+ const errorResponse = {
245
+ error: true,
246
+ message: error instanceof Error ? error.message : 'An unexpected error occurred',
247
+ statusCode: (error as any).statusCode || 500,
248
+ isRetryable: (error as any).isRetryable !== false,
249
+ provider: (error as any).provider || 'unknown',
250
+ };
251
+
252
+ if (error instanceof Error && error.message?.includes('API key')) {
253
+ return new Response(
254
+ JSON.stringify({
255
+ ...errorResponse,
256
+ message: 'Invalid or missing API key',
257
+ statusCode: 401,
258
+ isRetryable: false,
259
+ }),
260
+ {
261
+ status: 401,
262
+ headers: { 'Content-Type': 'application/json' },
263
+ statusText: 'Unauthorized',
264
+ },
265
+ );
266
+ }
267
+
268
+ // Handle token limit errors with helpful messages
269
+ if (
270
+ error instanceof Error &&
271
+ (error.message?.includes('max_tokens') ||
272
+ error.message?.includes('token') ||
273
+ error.message?.includes('exceeds') ||
274
+ error.message?.includes('maximum'))
275
+ ) {
276
+ return new Response(
277
+ JSON.stringify({
278
+ ...errorResponse,
279
+ message: `Token limit error: ${error.message}. Try reducing your request size or using a model with higher token limits.`,
280
+ statusCode: 400,
281
+ isRetryable: false,
282
+ }),
283
+ {
284
+ status: 400,
285
+ headers: { 'Content-Type': 'application/json' },
286
+ statusText: 'Token Limit Exceeded',
287
+ },
288
+ );
289
+ }
290
+
291
+ return new Response(JSON.stringify(errorResponse), {
292
+ status: errorResponse.statusCode,
293
+ headers: { 'Content-Type': 'application/json' },
294
+ statusText: 'Error',
295
+ });
296
+ }
297
+ }
298
+ }
@@ -0,0 +1,351 @@
1
+ /**
2
+ * Mandate API endpoint for autonomous code generation.
3
+ *
4
+ * Receives structured mandates from CorporateSwarm and executes
5
+ * code generation cycles autonomously with governance oversight.
6
+ */
7
+
8
+ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
9
+ import { createScopedLogger } from '~/utils/logger';
10
+ import type { Mandate, ExecutionResult } from '~/types/mandate';
11
+ import { eventRegistry } from '~/lib/runtime/execution-events';
12
+ import { createEventStreamResponse, broadcastEvent } from '~/lib/runtime/event-stream';
13
+
14
+ const logger = createScopedLogger('api.mandate');
15
+
16
+ /**
17
+ * Validate mandate structure and constraints.
18
+ */
19
+ function validateMandate(mandate: Mandate): { valid: boolean; errors: string[] } {
20
+ const errors: string[] = [];
21
+
22
+ // Validate mandate_id
23
+ if (!mandate.mandate_id || typeof mandate.mandate_id !== 'string') {
24
+ errors.push('mandate_id is required and must be a string');
25
+ }
26
+
27
+ // Validate objectives
28
+ if (!Array.isArray(mandate.objectives) || mandate.objectives.length === 0) {
29
+ errors.push('objectives must be a non-empty array');
30
+ }
31
+
32
+ // Validate constraints
33
+ if (!mandate.constraints) {
34
+ errors.push('constraints are required');
35
+ } else {
36
+ if (mandate.constraints.maxDependencies < 0) {
37
+ errors.push('maxDependencies must be non-negative');
38
+ }
39
+ if (mandate.constraints.maxFileSize < 0) {
40
+ errors.push('maxFileSize must be non-negative');
41
+ }
42
+ if (mandate.constraints.maxFiles < 0) {
43
+ errors.push('maxFiles must be non-negative');
44
+ }
45
+ }
46
+
47
+ // Validate budget
48
+ if (!mandate.budget) {
49
+ errors.push('budget is required');
50
+ } else {
51
+ if (mandate.budget.token < 0) {
52
+ errors.push('budget.token must be non-negative');
53
+ }
54
+ if (mandate.budget.time < 0) {
55
+ errors.push('budget.time must be non-negative');
56
+ }
57
+ if (mandate.budget.cost < 0) {
58
+ errors.push('budget.cost must be non-negative');
59
+ }
60
+ }
61
+
62
+ // Validate deliverables
63
+ if (!Array.isArray(mandate.deliverables) || mandate.deliverables.length === 0) {
64
+ errors.push('deliverables must be a non-empty array');
65
+ }
66
+
67
+ // Validate iteration_config
68
+ if (!mandate.iteration_config) {
69
+ errors.push('iteration_config is required');
70
+ } else {
71
+ if (mandate.iteration_config.max_iterations < 1) {
72
+ errors.push('max_iterations must be at least 1');
73
+ }
74
+ if (
75
+ mandate.iteration_config.quality_threshold < 0 ||
76
+ mandate.iteration_config.quality_threshold > 1
77
+ ) {
78
+ errors.push('quality_threshold must be between 0 and 1');
79
+ }
80
+ }
81
+
82
+ // Validate deployment config if enabled
83
+ if (mandate.deployment?.enabled) {
84
+ if (!mandate.deployment.provider) {
85
+ errors.push('deployment.provider is required when deployment is enabled');
86
+ } else {
87
+ const validProviders = ['netlify', 'vercel', 'github', 'gitlab'];
88
+ if (!validProviders.includes(mandate.deployment.provider)) {
89
+ errors.push(`deployment.provider must be one of: ${validProviders.join(', ')}`);
90
+ }
91
+ }
92
+ }
93
+
94
+ return {
95
+ valid: errors.length === 0,
96
+ errors,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Main mandate action handler.
102
+ */
103
+ export async function action(args: ActionFunctionArgs) {
104
+ return mandateAction(args);
105
+ }
106
+
107
+ async function mandateAction({ context, request }: ActionFunctionArgs) {
108
+ try {
109
+ // Parse mandate from request
110
+ const mandate: Mandate = await request.json();
111
+
112
+ logger.info(`Received mandate: ${mandate.mandate_id}`);
113
+
114
+ // Validate mandate
115
+ const validation = validateMandate(mandate);
116
+ if (!validation.valid) {
117
+ logger.error(`Mandate validation failed: ${validation.errors.join(', ')}`);
118
+ return new Response(
119
+ JSON.stringify({
120
+ success: false,
121
+ error: 'Invalid mandate',
122
+ errors: validation.errors,
123
+ }),
124
+ {
125
+ status: 400,
126
+ headers: { 'Content-Type': 'application/json' },
127
+ }
128
+ );
129
+ }
130
+
131
+ // Check if this is a request for event stream
132
+ const url = new URL(request.url);
133
+ const streamRequested = url.searchParams.get('stream') === 'true';
134
+
135
+ if (streamRequested) {
136
+ // Return event stream for real-time observability
137
+ return createEventStreamResponse(mandate.mandate_id);
138
+ }
139
+
140
+ // Check if Execution Governor is enabled
141
+ const governorEnabled = process.env.EXECUTION_GOVERNOR_ENABLED === 'true' ||
142
+ process.env.EXECUTION_GOVERNOR_URL !== undefined;
143
+ const governorUrl = process.env.EXECUTION_GOVERNOR_URL || 'http://localhost:3000';
144
+
145
+ if (governorEnabled) {
146
+ // Forward mandate to Execution Governor
147
+ try {
148
+ logger.info(`Forwarding mandate ${mandate.mandate_id} to Execution Governor at ${governorUrl}`);
149
+
150
+ const governorResponse = await fetch(`${governorUrl}/mandates`, {
151
+ method: 'POST',
152
+ headers: {
153
+ 'Content-Type': 'application/json',
154
+ },
155
+ body: JSON.stringify(mandate),
156
+ });
157
+
158
+ if (!governorResponse.ok) {
159
+ const errorText = await governorResponse.text();
160
+ logger.error(`Governor rejected mandate: ${governorResponse.status} - ${errorText}`);
161
+
162
+ // Fall back to direct execution if governor fails
163
+ logger.warn('Falling back to direct execution mode');
164
+ } else {
165
+ const governorData = await governorResponse.json() as { queue_position?: number; estimated_wait_time?: number };
166
+ logger.info(`Mandate ${mandate.mandate_id} queued in governor:`, governorData);
167
+
168
+ // Initialize event emitter for observability
169
+ const emitter = eventRegistry.getEmitter(mandate.mandate_id);
170
+
171
+ // Store mandate for later retrieval
172
+ eventRegistry.storeMandate(mandate.mandate_id, mandate);
173
+
174
+ emitter.emitLog('info', `Mandate ${mandate.mandate_id} queued in Execution Governor`, 'api');
175
+
176
+ return new Response(
177
+ JSON.stringify({
178
+ success: true,
179
+ mandate_id: mandate.mandate_id,
180
+ status: 'queued',
181
+ message: 'Mandate queued in Execution Governor',
182
+ queue_position: governorData.queue_position,
183
+ estimated_wait_time: governorData.estimated_wait_time,
184
+ event_stream_url: `/api/mandate?stream=true&mandate_id=${mandate.mandate_id}`,
185
+ governor_url: governorUrl,
186
+ }),
187
+ {
188
+ status: 202, // Accepted
189
+ headers: { 'Content-Type': 'application/json' },
190
+ }
191
+ );
192
+ }
193
+ } catch (error) {
194
+ logger.error('Error forwarding to governor, falling back to direct execution:', error);
195
+ // Fall through to direct execution
196
+ }
197
+ }
198
+
199
+ // Direct execution mode (fallback or when governor disabled)
200
+ // Initialize event emitter for this mandate
201
+ const emitter = eventRegistry.getEmitter(mandate.mandate_id);
202
+
203
+ // Store mandate for later retrieval
204
+ eventRegistry.storeMandate(mandate.mandate_id, mandate);
205
+
206
+ // Emit initial acceptance event
207
+ emitter.emitIterationStart(0, {
208
+ model_used: 'pending',
209
+ });
210
+
211
+ emitter.emitLog('info', `Mandate ${mandate.mandate_id} accepted and queued for execution`, 'api');
212
+
213
+ // Note: Actual execution will be handled client-side where WebContainer is available
214
+ // The mandate is validated and accepted here, execution happens via client-side MandateExecutor
215
+ logger.info(`Mandate ${mandate.mandate_id} accepted, ready for client-side execution`);
216
+
217
+ return new Response(
218
+ JSON.stringify({
219
+ success: true,
220
+ mandate_id: mandate.mandate_id,
221
+ status: 'accepted',
222
+ message: 'Mandate accepted, execution started',
223
+ event_stream_url: `/api/mandate?stream=true&mandate_id=${mandate.mandate_id}`,
224
+ }),
225
+ {
226
+ status: 202, // Accepted
227
+ headers: { 'Content-Type': 'application/json' },
228
+ }
229
+ );
230
+ } catch (error: unknown) {
231
+ logger.error('Error processing mandate:', error);
232
+
233
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
234
+
235
+ return new Response(
236
+ JSON.stringify({
237
+ success: false,
238
+ error: 'Failed to process mandate',
239
+ message: errorMessage,
240
+ }),
241
+ {
242
+ status: 500,
243
+ headers: { 'Content-Type': 'application/json' },
244
+ }
245
+ );
246
+ }
247
+ }
248
+
249
+ /**
250
+ * GET handler for mandate status and event polling.
251
+ */
252
+ export async function loader({ request }: ActionFunctionArgs) {
253
+ const url = new URL(request.url);
254
+
255
+ // Check if this is a request for active mandates list (no mandate_id required)
256
+ if (url.searchParams.get('list') === 'true') {
257
+ const allMandateIds = eventRegistry.getActiveMandates();
258
+ const mandates = allMandateIds.slice(-10).reverse().map(mandateId => {
259
+ const emitter = eventRegistry.getEmitter(mandateId);
260
+ const events = emitter.getEvents();
261
+ const latestEvent = events[events.length - 1];
262
+
263
+ return {
264
+ mandate_id: mandateId,
265
+ last_event_time: latestEvent?.timestamp || Date.now() / 1000,
266
+ event_count: events.length,
267
+ status: latestEvent?.type === 'iteration_end' ? 'completed' :
268
+ latestEvent?.type === 'error' ? 'failed' :
269
+ events.length > 0 ? 'running' : 'accepted'
270
+ };
271
+ });
272
+
273
+ return new Response(
274
+ JSON.stringify({
275
+ mandates,
276
+ count: mandates.length,
277
+ }),
278
+ {
279
+ status: 200,
280
+ headers: { 'Content-Type': 'application/json' },
281
+ }
282
+ );
283
+ }
284
+
285
+ // For other requests, mandate_id is required
286
+ const mandateId = url.searchParams.get('mandate_id');
287
+
288
+ if (!mandateId) {
289
+ return new Response(
290
+ JSON.stringify({
291
+ error: 'mandate_id parameter is required (or use ?list=true for mandates list)',
292
+ }),
293
+ {
294
+ status: 400,
295
+ headers: { 'Content-Type': 'application/json' },
296
+ }
297
+ );
298
+ }
299
+
300
+ // Check if this is a request for the mandate object itself
301
+ if (url.searchParams.get('get') === 'true') {
302
+ const storedMandate = eventRegistry.getMandate(mandateId);
303
+ if (storedMandate) {
304
+ return new Response(
305
+ JSON.stringify({
306
+ mandate: storedMandate,
307
+ }),
308
+ {
309
+ status: 200,
310
+ headers: { 'Content-Type': 'application/json' },
311
+ }
312
+ );
313
+ } else {
314
+ return new Response(
315
+ JSON.stringify({
316
+ error: 'Mandate not found',
317
+ }),
318
+ {
319
+ status: 404,
320
+ headers: { 'Content-Type': 'application/json' },
321
+ }
322
+ );
323
+ }
324
+ }
325
+
326
+ // Check if streaming is requested
327
+ const streamRequested = url.searchParams.get('stream') === 'true';
328
+ if (streamRequested) {
329
+ return createEventStreamResponse(mandateId);
330
+ }
331
+
332
+ // Return current events for polling
333
+ const { getMandateEvents, getMandateEventsSince } = await import('~/lib/runtime/event-stream');
334
+ const since = url.searchParams.get('since');
335
+ const events = since
336
+ ? getMandateEventsSince(mandateId, parseInt(since, 10))
337
+ : getMandateEvents(mandateId);
338
+
339
+ return new Response(
340
+ JSON.stringify({
341
+ mandate_id: mandateId,
342
+ events,
343
+ count: events.length,
344
+ }),
345
+ {
346
+ status: 200,
347
+ headers: { 'Content-Type': 'application/json' },
348
+ }
349
+ );
350
+ }
351
+
@@ -0,0 +1,16 @@
1
+ import { createScopedLogger } from '~/utils/logger';
2
+ import { MCPService } from '~/lib/services/mcpService';
3
+
4
+ const logger = createScopedLogger('api.mcp-check');
5
+
6
+ export async function loader() {
7
+ try {
8
+ const mcpService = MCPService.getInstance();
9
+ const serverTools = await mcpService.checkServersAvailabilities();
10
+
11
+ return Response.json(serverTools);
12
+ } catch (error) {
13
+ logger.error('Error checking MCP servers:', error);
14
+ return Response.json({ error: 'Failed to check MCP servers' }, { status: 500 });
15
+ }
16
+ }
@@ -0,0 +1,23 @@
1
+ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
+ import { createScopedLogger } from '~/utils/logger';
3
+ import { MCPService, type MCPConfig } from '~/lib/services/mcpService';
4
+
5
+ const logger = createScopedLogger('api.mcp-update-config');
6
+
7
+ export async function action({ request }: ActionFunctionArgs) {
8
+ try {
9
+ const mcpConfig = (await request.json()) as MCPConfig;
10
+
11
+ if (!mcpConfig || typeof mcpConfig !== 'object') {
12
+ return Response.json({ error: 'Invalid MCP servers configuration' }, { status: 400 });
13
+ }
14
+
15
+ const mcpService = MCPService.getInstance();
16
+ const serverTools = await mcpService.updateConfig(mcpConfig);
17
+
18
+ return Response.json(serverTools);
19
+ } catch (error) {
20
+ logger.error('Error updating MCP config:', error);
21
+ return Response.json({ error: 'Failed to update MCP config' }, { status: 500 });
22
+ }
23
+ }
@@ -0,0 +1,2 @@
1
+ import { loader } from './api.models';
2
+ export { loader };