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,463 @@
1
+ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
+ import { createDataStream, generateId } from 'ai';
3
+ import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS, type FileMap } from '~/lib/.server/llm/constants';
4
+ import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts';
5
+ import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text';
6
+ import SwitchableStream from '~/lib/.server/llm/switchable-stream';
7
+ import type { IProviderSetting } from '~/types/model';
8
+ import { createScopedLogger } from '~/utils/logger';
9
+ import { getFilePaths, selectContext } from '~/lib/.server/llm/select-context';
10
+ import type { ContextAnnotation, ProgressAnnotation } from '~/types/context';
11
+ import { WORK_DIR } from '~/utils/constants';
12
+ import { createSummary } from '~/lib/.server/llm/create-summary';
13
+ import { extractPropertiesFromMessage } from '~/lib/.server/llm/utils';
14
+ import type { DesignScheme } from '~/types/design-scheme';
15
+ import { MCPService } from '~/lib/services/mcpService';
16
+ import { StreamRecoveryManager } from '~/lib/.server/llm/stream-recovery';
17
+
18
+ export async function action(args: ActionFunctionArgs) {
19
+ return chatAction(args);
20
+ }
21
+
22
+ const logger = createScopedLogger('api.chat');
23
+
24
+ function parseCookies(cookieHeader: string): Record<string, string> {
25
+ const cookies: Record<string, string> = {};
26
+
27
+ const items = cookieHeader.split(';').map((cookie) => cookie.trim());
28
+
29
+ items.forEach((item) => {
30
+ const [name, ...rest] = item.split('=');
31
+
32
+ if (name && rest) {
33
+ const decodedName = decodeURIComponent(name.trim());
34
+ const decodedValue = decodeURIComponent(rest.join('=').trim());
35
+ cookies[decodedName] = decodedValue;
36
+ }
37
+ });
38
+
39
+ return cookies;
40
+ }
41
+
42
+ async function chatAction({ context, request }: ActionFunctionArgs) {
43
+ const streamRecovery = new StreamRecoveryManager({
44
+ timeout: 45000,
45
+ maxRetries: 2,
46
+ onTimeout: () => {
47
+ logger.warn('Stream timeout - attempting recovery');
48
+ },
49
+ });
50
+
51
+ const { messages, files, promptId, contextOptimization, supabase, chatMode, designScheme, maxLLMSteps } =
52
+ await request.json<{
53
+ messages: Messages;
54
+ files: any;
55
+ promptId?: string;
56
+ contextOptimization: boolean;
57
+ chatMode: 'discuss' | 'build';
58
+ designScheme?: DesignScheme;
59
+ supabase?: {
60
+ isConnected: boolean;
61
+ hasSelectedProject: boolean;
62
+ credentials?: {
63
+ anonKey?: string;
64
+ supabaseUrl?: string;
65
+ };
66
+ };
67
+ maxLLMSteps: number;
68
+ }>();
69
+
70
+ const cookieHeader = request.headers.get('Cookie');
71
+ const apiKeys = JSON.parse(parseCookies(cookieHeader || '').apiKeys || '{}');
72
+ const providerSettings: Record<string, IProviderSetting> = JSON.parse(
73
+ parseCookies(cookieHeader || '').providers || '{}',
74
+ );
75
+
76
+ const stream = new SwitchableStream();
77
+
78
+ const cumulativeUsage = {
79
+ completionTokens: 0,
80
+ promptTokens: 0,
81
+ totalTokens: 0,
82
+ };
83
+ const encoder: TextEncoder = new TextEncoder();
84
+ let progressCounter: number = 1;
85
+
86
+ try {
87
+ const mcpService = MCPService.getInstance();
88
+ const totalMessageContent = messages.reduce((acc, message) => acc + message.content, '');
89
+ logger.debug(`Total message length: ${totalMessageContent.split(' ').length}, words`);
90
+
91
+ let lastChunk: string | undefined = undefined;
92
+
93
+ const dataStream = createDataStream({
94
+ async execute(dataStream) {
95
+ streamRecovery.startMonitoring();
96
+
97
+ const filePaths = getFilePaths(files || {});
98
+ let filteredFiles: FileMap | undefined = undefined;
99
+ let summary: string | undefined = undefined;
100
+ let messageSliceId = 0;
101
+
102
+ const processedMessages = await mcpService.processToolInvocations(messages, dataStream);
103
+
104
+ if (processedMessages.length > 3) {
105
+ messageSliceId = processedMessages.length - 3;
106
+ }
107
+
108
+ if (filePaths.length > 0 && contextOptimization) {
109
+ logger.debug('Generating Chat Summary');
110
+ dataStream.writeData({
111
+ type: 'progress',
112
+ label: 'summary',
113
+ status: 'in-progress',
114
+ order: progressCounter++,
115
+ message: 'Analysing Request',
116
+ } satisfies ProgressAnnotation);
117
+
118
+ // Create a summary of the chat
119
+ console.log(`Messages count: ${processedMessages.length}`);
120
+
121
+ summary = await createSummary({
122
+ messages: [...processedMessages],
123
+ env: context.cloudflare?.env,
124
+ apiKeys,
125
+ providerSettings,
126
+ promptId,
127
+ contextOptimization,
128
+ onFinish(resp) {
129
+ if (resp.usage) {
130
+ logger.debug('createSummary token usage', JSON.stringify(resp.usage));
131
+ cumulativeUsage.completionTokens += resp.usage.completionTokens || 0;
132
+ cumulativeUsage.promptTokens += resp.usage.promptTokens || 0;
133
+ cumulativeUsage.totalTokens += resp.usage.totalTokens || 0;
134
+ }
135
+ },
136
+ });
137
+ dataStream.writeData({
138
+ type: 'progress',
139
+ label: 'summary',
140
+ status: 'complete',
141
+ order: progressCounter++,
142
+ message: 'Analysis Complete',
143
+ } satisfies ProgressAnnotation);
144
+
145
+ dataStream.writeMessageAnnotation({
146
+ type: 'chatSummary',
147
+ summary,
148
+ chatId: processedMessages.slice(-1)?.[0]?.id,
149
+ } as ContextAnnotation);
150
+
151
+ // Update context buffer
152
+ logger.debug('Updating Context Buffer');
153
+ dataStream.writeData({
154
+ type: 'progress',
155
+ label: 'context',
156
+ status: 'in-progress',
157
+ order: progressCounter++,
158
+ message: 'Determining Files to Read',
159
+ } satisfies ProgressAnnotation);
160
+
161
+ // Select context files
162
+ console.log(`Messages count: ${processedMessages.length}`);
163
+ filteredFiles = await selectContext({
164
+ messages: [...processedMessages],
165
+ env: context.cloudflare?.env,
166
+ apiKeys,
167
+ files,
168
+ providerSettings,
169
+ promptId,
170
+ contextOptimization,
171
+ summary,
172
+ onFinish(resp) {
173
+ if (resp.usage) {
174
+ logger.debug('selectContext token usage', JSON.stringify(resp.usage));
175
+ cumulativeUsage.completionTokens += resp.usage.completionTokens || 0;
176
+ cumulativeUsage.promptTokens += resp.usage.promptTokens || 0;
177
+ cumulativeUsage.totalTokens += resp.usage.totalTokens || 0;
178
+ }
179
+ },
180
+ });
181
+
182
+ if (filteredFiles) {
183
+ logger.debug(`files in context : ${JSON.stringify(Object.keys(filteredFiles))}`);
184
+ }
185
+
186
+ dataStream.writeMessageAnnotation({
187
+ type: 'codeContext',
188
+ files: Object.keys(filteredFiles).map((key) => {
189
+ let path = key;
190
+
191
+ if (path.startsWith(WORK_DIR)) {
192
+ path = path.replace(WORK_DIR, '');
193
+ }
194
+
195
+ return path;
196
+ }),
197
+ } as ContextAnnotation);
198
+
199
+ dataStream.writeData({
200
+ type: 'progress',
201
+ label: 'context',
202
+ status: 'complete',
203
+ order: progressCounter++,
204
+ message: 'Code Files Selected',
205
+ } satisfies ProgressAnnotation);
206
+
207
+ // logger.debug('Code Files Selected');
208
+ }
209
+
210
+ const options: StreamingOptions = {
211
+ supabaseConnection: supabase,
212
+ toolChoice: 'auto',
213
+ tools: mcpService.toolsWithoutExecute,
214
+ maxSteps: maxLLMSteps,
215
+ onStepFinish: ({ toolCalls }) => {
216
+ // add tool call annotations for frontend processing
217
+ toolCalls.forEach((toolCall) => {
218
+ mcpService.processToolCall(toolCall, dataStream);
219
+ });
220
+ },
221
+ onFinish: async ({ text: content, finishReason, usage }) => {
222
+ logger.debug('usage', JSON.stringify(usage));
223
+
224
+ if (usage) {
225
+ cumulativeUsage.completionTokens += usage.completionTokens || 0;
226
+ cumulativeUsage.promptTokens += usage.promptTokens || 0;
227
+ cumulativeUsage.totalTokens += usage.totalTokens || 0;
228
+ }
229
+
230
+ if (finishReason !== 'length') {
231
+ dataStream.writeMessageAnnotation({
232
+ type: 'usage',
233
+ value: {
234
+ completionTokens: cumulativeUsage.completionTokens,
235
+ promptTokens: cumulativeUsage.promptTokens,
236
+ totalTokens: cumulativeUsage.totalTokens,
237
+ },
238
+ });
239
+ dataStream.writeData({
240
+ type: 'progress',
241
+ label: 'response',
242
+ status: 'complete',
243
+ order: progressCounter++,
244
+ message: 'Response Generated',
245
+ } satisfies ProgressAnnotation);
246
+ await new Promise((resolve) => setTimeout(resolve, 0));
247
+
248
+ // stream.close();
249
+ return;
250
+ }
251
+
252
+ if (stream.switches >= MAX_RESPONSE_SEGMENTS) {
253
+ throw Error('Cannot continue message: Maximum segments reached');
254
+ }
255
+
256
+ const switchesLeft = MAX_RESPONSE_SEGMENTS - stream.switches;
257
+
258
+ logger.info(`Reached max token limit (${MAX_TOKENS}): Continuing message (${switchesLeft} switches left)`);
259
+
260
+ const lastUserMessage = processedMessages.filter((x) => x.role == 'user').slice(-1)[0];
261
+ const { model, provider } = extractPropertiesFromMessage(lastUserMessage);
262
+ processedMessages.push({ id: generateId(), role: 'assistant', content });
263
+ processedMessages.push({
264
+ id: generateId(),
265
+ role: 'user',
266
+ content: `[Model: ${model}]\n\n[Provider: ${provider}]\n\n${CONTINUE_PROMPT}`,
267
+ });
268
+
269
+ const result = await streamText({
270
+ messages: [...processedMessages],
271
+ env: context.cloudflare?.env,
272
+ options,
273
+ apiKeys,
274
+ files,
275
+ providerSettings,
276
+ promptId,
277
+ contextOptimization,
278
+ contextFiles: filteredFiles,
279
+ chatMode,
280
+ designScheme,
281
+ summary,
282
+ messageSliceId,
283
+ });
284
+
285
+ result.mergeIntoDataStream(dataStream);
286
+
287
+ (async () => {
288
+ for await (const part of result.fullStream) {
289
+ if (part.type === 'error') {
290
+ const error: any = part.error;
291
+ logger.error(`${error}`);
292
+
293
+ return;
294
+ }
295
+ }
296
+ })();
297
+
298
+ return;
299
+ },
300
+ };
301
+
302
+ dataStream.writeData({
303
+ type: 'progress',
304
+ label: 'response',
305
+ status: 'in-progress',
306
+ order: progressCounter++,
307
+ message: 'Generating Response',
308
+ } satisfies ProgressAnnotation);
309
+
310
+ const result = await streamText({
311
+ messages: [...processedMessages],
312
+ env: context.cloudflare?.env,
313
+ options,
314
+ apiKeys,
315
+ files,
316
+ providerSettings,
317
+ promptId,
318
+ contextOptimization,
319
+ contextFiles: filteredFiles,
320
+ chatMode,
321
+ designScheme,
322
+ summary,
323
+ messageSliceId,
324
+ });
325
+
326
+ (async () => {
327
+ for await (const part of result.fullStream) {
328
+ streamRecovery.updateActivity();
329
+
330
+ if (part.type === 'error') {
331
+ const error: any = part.error;
332
+ logger.error('Streaming error:', error);
333
+ streamRecovery.stop();
334
+
335
+ // Enhanced error handling for common streaming issues
336
+ if (error.message?.includes('Invalid JSON response')) {
337
+ logger.error('Invalid JSON response detected - likely malformed API response');
338
+ } else if (error.message?.includes('token')) {
339
+ logger.error('Token-related error detected - possible token limit exceeded');
340
+ }
341
+
342
+ return;
343
+ }
344
+ }
345
+ streamRecovery.stop();
346
+ })();
347
+ result.mergeIntoDataStream(dataStream);
348
+ },
349
+ onError: (error: any) => {
350
+ // Provide more specific error messages for common issues
351
+ const errorMessage = error.message || 'Unknown error';
352
+
353
+ if (errorMessage.includes('model') && errorMessage.includes('not found')) {
354
+ return 'Custom error: Invalid model selected. Please check that the model name is correct and available.';
355
+ }
356
+
357
+ if (errorMessage.includes('Invalid JSON response')) {
358
+ return 'Custom error: The AI service returned an invalid response. This may be due to an invalid model name, API rate limiting, or server issues. Try selecting a different model or check your API key.';
359
+ }
360
+
361
+ if (
362
+ errorMessage.includes('API key') ||
363
+ errorMessage.includes('unauthorized') ||
364
+ errorMessage.includes('authentication')
365
+ ) {
366
+ return 'Custom error: Invalid or missing API key. Please check your API key configuration.';
367
+ }
368
+
369
+ if (errorMessage.includes('token') && errorMessage.includes('limit')) {
370
+ return 'Custom error: Token limit exceeded. The conversation is too long for the selected model. Try using a model with larger context window or start a new conversation.';
371
+ }
372
+
373
+ if (errorMessage.includes('rate limit') || errorMessage.includes('429')) {
374
+ return 'Custom error: API rate limit exceeded. Please wait a moment before trying again.';
375
+ }
376
+
377
+ if (errorMessage.includes('network') || errorMessage.includes('timeout')) {
378
+ return 'Custom error: Network error. Please check your internet connection and try again.';
379
+ }
380
+
381
+ return `Custom error: ${errorMessage}`;
382
+ },
383
+ }).pipeThrough(
384
+ new TransformStream({
385
+ transform: (chunk, controller) => {
386
+ if (!lastChunk) {
387
+ lastChunk = ' ';
388
+ }
389
+
390
+ if (typeof chunk === 'string') {
391
+ if (chunk.startsWith('g') && !lastChunk.startsWith('g')) {
392
+ controller.enqueue(encoder.encode(`0: "<div class=\\"__boltThought__\\">"\n`));
393
+ }
394
+
395
+ if (lastChunk.startsWith('g') && !chunk.startsWith('g')) {
396
+ controller.enqueue(encoder.encode(`0: "</div>\\n"\n`));
397
+ }
398
+ }
399
+
400
+ lastChunk = chunk;
401
+
402
+ let transformedChunk = chunk;
403
+
404
+ if (typeof chunk === 'string' && chunk.startsWith('g')) {
405
+ let content = chunk.split(':').slice(1).join(':');
406
+
407
+ if (content.endsWith('\n')) {
408
+ content = content.slice(0, content.length - 1);
409
+ }
410
+
411
+ transformedChunk = `0:${content}\n`;
412
+ }
413
+
414
+ // Convert the string stream to a byte stream
415
+ const str = typeof transformedChunk === 'string' ? transformedChunk : JSON.stringify(transformedChunk);
416
+ controller.enqueue(encoder.encode(str));
417
+ },
418
+ }),
419
+ );
420
+
421
+ return new Response(dataStream, {
422
+ status: 200,
423
+ headers: {
424
+ 'Content-Type': 'text/event-stream; charset=utf-8',
425
+ Connection: 'keep-alive',
426
+ 'Cache-Control': 'no-cache',
427
+ 'Text-Encoding': 'chunked',
428
+ },
429
+ });
430
+ } catch (error: any) {
431
+ logger.error(error);
432
+
433
+ const errorResponse = {
434
+ error: true,
435
+ message: error.message || 'An unexpected error occurred',
436
+ statusCode: error.statusCode || 500,
437
+ isRetryable: error.isRetryable !== false, // Default to retryable unless explicitly false
438
+ provider: error.provider || 'unknown',
439
+ };
440
+
441
+ if (error.message?.includes('API key')) {
442
+ return new Response(
443
+ JSON.stringify({
444
+ ...errorResponse,
445
+ message: 'Invalid or missing API key',
446
+ statusCode: 401,
447
+ isRetryable: false,
448
+ }),
449
+ {
450
+ status: 401,
451
+ headers: { 'Content-Type': 'application/json' },
452
+ statusText: 'Unauthorized',
453
+ },
454
+ );
455
+ }
456
+
457
+ return new Response(JSON.stringify(errorResponse), {
458
+ status: errorResponse.statusCode,
459
+ headers: { 'Content-Type': 'application/json' },
460
+ statusText: 'Error',
461
+ });
462
+ }
463
+ }
@@ -0,0 +1,41 @@
1
+ import type { LoaderFunction } from '@remix-run/cloudflare';
2
+ import { LLMManager } from '~/lib/modules/llm/manager';
3
+ import { getApiKeysFromCookie } from '~/lib/api/cookies';
4
+
5
+ export const loader: LoaderFunction = async ({ context, request }) => {
6
+ const url = new URL(request.url);
7
+ const provider = url.searchParams.get('provider');
8
+
9
+ if (!provider) {
10
+ return Response.json({ isSet: false });
11
+ }
12
+
13
+ const llmManager = LLMManager.getInstance(context?.cloudflare?.env as any);
14
+ const providerInstance = llmManager.getProvider(provider);
15
+
16
+ if (!providerInstance || !providerInstance.config.apiTokenKey) {
17
+ return Response.json({ isSet: false });
18
+ }
19
+
20
+ const envVarName = providerInstance.config.apiTokenKey;
21
+
22
+ // Get API keys from cookie
23
+ const cookieHeader = request.headers.get('Cookie');
24
+ const apiKeys = getApiKeysFromCookie(cookieHeader);
25
+
26
+ /*
27
+ * Check API key in order of precedence:
28
+ * 1. Client-side API keys (from cookies)
29
+ * 2. Server environment variables (from Cloudflare env)
30
+ * 3. Process environment variables (from .env.local)
31
+ * 4. LLMManager environment variables
32
+ */
33
+ const isSet = !!(
34
+ apiKeys?.[provider] ||
35
+ (context?.cloudflare?.env as Record<string, any>)?.[envVarName] ||
36
+ process.env[envVarName] ||
37
+ llmManager.env[envVarName]
38
+ );
39
+
40
+ return Response.json({ isSet });
41
+ };
@@ -0,0 +1,110 @@
1
+ import type { LoaderFunction } from '@remix-run/cloudflare';
2
+ import { json } from '@remix-run/cloudflare';
3
+ import { LLMManager } from '~/lib/modules/llm/manager';
4
+ import { LOCAL_PROVIDERS } from '~/lib/stores/settings';
5
+
6
+ interface ConfiguredProvider {
7
+ name: string;
8
+ isConfigured: boolean;
9
+ configMethod: 'environment' | 'none';
10
+ }
11
+
12
+ interface ConfiguredProvidersResponse {
13
+ providers: ConfiguredProvider[];
14
+ }
15
+
16
+ /**
17
+ * API endpoint that detects which providers are configured via environment variables
18
+ * This helps auto-enable providers that have been set up by the user
19
+ */
20
+ export const loader: LoaderFunction = async ({ context }) => {
21
+ try {
22
+ const llmManager = LLMManager.getInstance(context?.cloudflare?.env as any);
23
+ const configuredProviders: ConfiguredProvider[] = [];
24
+
25
+ // Check each local provider for environment configuration
26
+ for (const providerName of LOCAL_PROVIDERS) {
27
+ const providerInstance = llmManager.getProvider(providerName);
28
+ let isConfigured = false;
29
+ let configMethod: 'environment' | 'none' = 'none';
30
+
31
+ if (providerInstance) {
32
+ const config = providerInstance.config;
33
+
34
+ /*
35
+ * Check if required environment variables are set
36
+ * For providers with baseUrlKey (Ollama, LMStudio, OpenAILike)
37
+ */
38
+ if (config.baseUrlKey) {
39
+ const baseUrlEnvVar = config.baseUrlKey;
40
+ const cloudflareEnv = (context?.cloudflare?.env as Record<string, any>)?.[baseUrlEnvVar];
41
+ const processEnv = process.env[baseUrlEnvVar];
42
+ const managerEnv = llmManager.env[baseUrlEnvVar];
43
+
44
+ const envBaseUrl = cloudflareEnv || processEnv || managerEnv;
45
+
46
+ /*
47
+ * Only consider configured if environment variable is explicitly set
48
+ * Don't count default config.baseUrl values or placeholder values
49
+ */
50
+ const isValidEnvValue =
51
+ envBaseUrl &&
52
+ typeof envBaseUrl === 'string' &&
53
+ envBaseUrl.trim().length > 0 &&
54
+ !envBaseUrl.includes('your_') && // Filter out placeholder values like "your_openai_like_base_url_here"
55
+ !envBaseUrl.includes('_here') &&
56
+ envBaseUrl.startsWith('http'); // Must be a valid URL
57
+
58
+ if (isValidEnvValue) {
59
+ isConfigured = true;
60
+ configMethod = 'environment';
61
+ }
62
+ }
63
+
64
+ // For providers that might need API keys as well (check this separately, not as fallback)
65
+ if (config.apiTokenKey && !isConfigured) {
66
+ const apiTokenEnvVar = config.apiTokenKey;
67
+ const envApiToken =
68
+ (context?.cloudflare?.env as Record<string, any>)?.[apiTokenEnvVar] ||
69
+ process.env[apiTokenEnvVar] ||
70
+ llmManager.env[apiTokenEnvVar];
71
+
72
+ // Only consider configured if API key is set and not a placeholder
73
+ const isValidApiToken =
74
+ envApiToken &&
75
+ typeof envApiToken === 'string' &&
76
+ envApiToken.trim().length > 0 &&
77
+ !envApiToken.includes('your_') && // Filter out placeholder values
78
+ !envApiToken.includes('_here') &&
79
+ envApiToken.length > 10; // API keys are typically longer than 10 chars
80
+
81
+ if (isValidApiToken) {
82
+ isConfigured = true;
83
+ configMethod = 'environment';
84
+ }
85
+ }
86
+ }
87
+
88
+ configuredProviders.push({
89
+ name: providerName,
90
+ isConfigured,
91
+ configMethod,
92
+ });
93
+ }
94
+
95
+ return json<ConfiguredProvidersResponse>({
96
+ providers: configuredProviders,
97
+ });
98
+ } catch (error) {
99
+ console.error('Error detecting configured providers:', error);
100
+
101
+ // Return default state on error
102
+ return json<ConfiguredProvidersResponse>({
103
+ providers: LOCAL_PROVIDERS.map((name) => ({
104
+ name,
105
+ isConfigured: false,
106
+ configMethod: 'none' as const,
107
+ })),
108
+ });
109
+ }
110
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * CorporateSwarm status API endpoint.
3
+ *
4
+ * Queries CorporateSwarm for proposal and mandate status.
5
+ */
6
+
7
+ import { type LoaderFunctionArgs, json } from '@remix-run/cloudflare';
8
+ import { createScopedLogger } from '~/utils/logger';
9
+
10
+ const logger = createScopedLogger('api.corporate-swarm-status');
11
+
12
+ export async function loader({ request }: LoaderFunctionArgs) {
13
+ const url = new URL(request.url);
14
+ const proposalId = url.searchParams.get("proposal_id");
15
+ const mandateId = url.searchParams.get("mandate_id");
16
+
17
+ if (!proposalId && !mandateId) {
18
+ return json({ error: "proposal_id or mandate_id is required" }, { status: 400 });
19
+ }
20
+
21
+ try {
22
+ const corporateSwarmUrl = process.env.CORPORATE_SWARM_URL || "http://localhost:8000";
23
+ let data = null;
24
+
25
+ if (proposalId) {
26
+ const response = await fetch(`${corporateSwarmUrl}/api/proposal/${proposalId}`, {
27
+ headers: { "Content-Type": "application/json" },
28
+ signal: AbortSignal.timeout(5000)
29
+ });
30
+
31
+ if (response.ok) {
32
+ data = await response.json();
33
+ } else {
34
+ return json({ error: "Proposal not found" }, { status: 404 });
35
+ }
36
+ } else if (mandateId) {
37
+ const response = await fetch(`${corporateSwarmUrl}/api/mandate/${mandateId}`, {
38
+ headers: { "Content-Type": "application/json" },
39
+ signal: AbortSignal.timeout(5000)
40
+ });
41
+
42
+ if (response.ok) {
43
+ data = await response.json();
44
+ } else {
45
+ return json({ error: "Mandate not found" }, { status: 404 });
46
+ }
47
+ }
48
+
49
+ return json(data || {});
50
+ } catch (error) {
51
+ logger.error(`Error fetching CorporateSwarm status: ${error}`);
52
+ return json({ error: "Failed to fetch CorporateSwarm status" }, { status: 500 });
53
+ }
54
+ }
55
+