crca 1.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (501) hide show
  1. .github/ISSUE_TEMPLATE/bug_report.md +65 -0
  2. .github/ISSUE_TEMPLATE/feature_request.md +41 -0
  3. .github/PULL_REQUEST_TEMPLATE.md +20 -0
  4. .github/workflows/publish-manual.yml +61 -0
  5. .github/workflows/publish.yml +64 -0
  6. .gitignore +214 -0
  7. CRCA.py +4156 -0
  8. LICENSE +201 -0
  9. MANIFEST.in +43 -0
  10. PKG-INFO +5035 -0
  11. README.md +4959 -0
  12. __init__.py +17 -0
  13. branches/CRCA-Q.py +2728 -0
  14. branches/crca_cg/corposwarm.py +9065 -0
  15. branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
  16. branches/crca_cg/package.json +5 -0
  17. branches/crca_cg/test_bolt_integration.py +446 -0
  18. branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
  19. branches/crca_cg/test_new_features.py +163 -0
  20. branches/crca_sd/__init__.py +149 -0
  21. branches/crca_sd/crca_sd_core.py +770 -0
  22. branches/crca_sd/crca_sd_governance.py +1325 -0
  23. branches/crca_sd/crca_sd_mpc.py +1130 -0
  24. branches/crca_sd/crca_sd_realtime.py +1844 -0
  25. branches/crca_sd/crca_sd_tui.py +1133 -0
  26. crca-1.4.0.dist-info/METADATA +5035 -0
  27. crca-1.4.0.dist-info/RECORD +501 -0
  28. crca-1.4.0.dist-info/WHEEL +4 -0
  29. crca-1.4.0.dist-info/licenses/LICENSE +201 -0
  30. docs/CRCA-Q.md +2333 -0
  31. examples/config.yaml.example +25 -0
  32. examples/crca_sd_example.py +513 -0
  33. examples/data_broker_example.py +294 -0
  34. examples/logistics_corporation.py +861 -0
  35. examples/palantir_example.py +299 -0
  36. examples/policy_bench.py +934 -0
  37. examples/pridnestrovia-sd.py +705 -0
  38. examples/pridnestrovia_realtime.py +1902 -0
  39. prompts/__init__.py +10 -0
  40. prompts/default_crca.py +101 -0
  41. pyproject.toml +151 -0
  42. requirements.txt +76 -0
  43. schemas/__init__.py +43 -0
  44. schemas/mcpSchemas.py +51 -0
  45. schemas/policy.py +458 -0
  46. templates/__init__.py +38 -0
  47. templates/base_specialized_agent.py +195 -0
  48. templates/drift_detection.py +325 -0
  49. templates/examples/causal_agent_template.py +309 -0
  50. templates/examples/drag_drop_example.py +213 -0
  51. templates/examples/logistics_agent_template.py +207 -0
  52. templates/examples/trading_agent_template.py +206 -0
  53. templates/feature_mixins.py +253 -0
  54. templates/graph_management.py +442 -0
  55. templates/llm_integration.py +194 -0
  56. templates/module_registry.py +276 -0
  57. templates/mpc_planner.py +280 -0
  58. templates/policy_loop.py +1168 -0
  59. templates/prediction_framework.py +448 -0
  60. templates/statistical_methods.py +778 -0
  61. tests/sanity.yml +31 -0
  62. tests/sanity_check +406 -0
  63. tests/test_core.py +47 -0
  64. tests/test_crca_excel.py +166 -0
  65. tests/test_crca_sd.py +780 -0
  66. tests/test_data_broker.py +424 -0
  67. tests/test_palantir.py +349 -0
  68. tools/__init__.py +38 -0
  69. tools/actuators.py +437 -0
  70. tools/bolt.diy/Dockerfile +103 -0
  71. tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
  72. tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
  73. tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
  74. tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
  75. tools/bolt.diy/app/components/@settings/index.ts +12 -0
  76. tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
  77. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
  78. tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
  79. tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
  80. tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
  81. tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
  82. tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
  83. tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
  84. tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
  85. tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
  86. tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
  87. tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
  88. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
  89. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
  90. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
  91. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
  92. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
  93. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
  94. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
  95. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
  96. tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
  97. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
  98. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
  99. tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
  100. tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
  101. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
  102. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
  103. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
  104. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
  105. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
  106. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
  107. tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
  108. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
  109. tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
  110. tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
  111. tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
  112. tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
  113. tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
  114. tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
  115. tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
  116. tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
  117. tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
  118. tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
  119. tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
  120. tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
  121. tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
  122. tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
  123. tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
  124. tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
  125. tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
  126. tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
  127. tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
  128. tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
  129. tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
  130. tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
  131. tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
  132. tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
  133. tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
  134. tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
  135. tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
  136. tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
  137. tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
  138. tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
  139. tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
  140. tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
  141. tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
  142. tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
  143. tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
  144. tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
  145. tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
  146. tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
  147. tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
  148. tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
  149. tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
  150. tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
  151. tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
  152. tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
  153. tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
  154. tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
  155. tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
  156. tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
  157. tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
  158. tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
  159. tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
  160. tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
  161. tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
  162. tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
  163. tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
  164. tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
  165. tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
  166. tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
  167. tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
  168. tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
  169. tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
  170. tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
  171. tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
  172. tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
  173. tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
  174. tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
  175. tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
  176. tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
  177. tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
  178. tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
  179. tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
  180. tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
  181. tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
  182. tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
  183. tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
  184. tools/bolt.diy/app/components/header/Header.tsx +42 -0
  185. tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
  186. tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
  187. tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
  188. tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
  189. tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
  190. tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
  191. tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
  192. tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
  193. tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
  194. tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
  195. tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
  196. tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
  197. tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
  198. tools/bolt.diy/app/components/txt +1 -0
  199. tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
  200. tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
  201. tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
  202. tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
  203. tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
  204. tools/bolt.diy/app/components/ui/Button.tsx +46 -0
  205. tools/bolt.diy/app/components/ui/Card.tsx +55 -0
  206. tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
  207. tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
  208. tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
  209. tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
  210. tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
  211. tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
  212. tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
  213. tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
  214. tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
  215. tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
  216. tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
  217. tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
  218. tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
  219. tools/bolt.diy/app/components/ui/Input.tsx +22 -0
  220. tools/bolt.diy/app/components/ui/Label.tsx +20 -0
  221. tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
  222. tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
  223. tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
  224. tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
  225. tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
  226. tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
  227. tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
  228. tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
  229. tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
  230. tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
  231. tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
  232. tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
  233. tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
  234. tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
  235. tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
  236. tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
  237. tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
  238. tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
  239. tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
  240. tools/bolt.diy/app/components/ui/index.ts +38 -0
  241. tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
  242. tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
  243. tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
  244. tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
  245. tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
  246. tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
  247. tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
  248. tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
  249. tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
  250. tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
  251. tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
  252. tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
  253. tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
  254. tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
  255. tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
  256. tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
  257. tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
  258. tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
  259. tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
  260. tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
  261. tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
  262. tools/bolt.diy/app/entry.client.tsx +7 -0
  263. tools/bolt.diy/app/entry.server.tsx +80 -0
  264. tools/bolt.diy/app/root.tsx +156 -0
  265. tools/bolt.diy/app/routes/_index.tsx +175 -0
  266. tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
  267. tools/bolt.diy/app/routes/api.chat.ts +463 -0
  268. tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
  269. tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
  270. tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
  271. tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
  272. tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
  273. tools/bolt.diy/app/routes/api.git-info.ts +69 -0
  274. tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
  275. tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
  276. tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
  277. tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
  278. tools/bolt.diy/app/routes/api.github-template.ts +242 -0
  279. tools/bolt.diy/app/routes/api.github-user.ts +287 -0
  280. tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
  281. tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
  282. tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
  283. tools/bolt.diy/app/routes/api.health.ts +8 -0
  284. tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
  285. tools/bolt.diy/app/routes/api.mandate.ts +351 -0
  286. tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
  287. tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
  288. tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
  289. tools/bolt.diy/app/routes/api.models.ts +90 -0
  290. tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
  291. tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
  292. tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
  293. tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
  294. tools/bolt.diy/app/routes/api.supabase.ts +56 -0
  295. tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
  296. tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
  297. tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
  298. tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
  299. tools/bolt.diy/app/routes/api.update.ts +21 -0
  300. tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
  301. tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
  302. tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
  303. tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
  304. tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
  305. tools/bolt.diy/app/routes/git.tsx +25 -0
  306. tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
  307. tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
  308. tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
  309. tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
  310. tools/bolt.diy/app/styles/animations.scss +49 -0
  311. tools/bolt.diy/app/styles/components/code.scss +9 -0
  312. tools/bolt.diy/app/styles/components/editor.scss +135 -0
  313. tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
  314. tools/bolt.diy/app/styles/components/terminal.scss +3 -0
  315. tools/bolt.diy/app/styles/components/toast.scss +23 -0
  316. tools/bolt.diy/app/styles/diff-view.css +72 -0
  317. tools/bolt.diy/app/styles/index.scss +73 -0
  318. tools/bolt.diy/app/styles/variables.scss +255 -0
  319. tools/bolt.diy/app/styles/z-index.scss +37 -0
  320. tools/bolt.diy/app/types/GitHub.ts +182 -0
  321. tools/bolt.diy/app/types/GitLab.ts +103 -0
  322. tools/bolt.diy/app/types/actions.ts +85 -0
  323. tools/bolt.diy/app/types/artifact.ts +5 -0
  324. tools/bolt.diy/app/types/context.ts +26 -0
  325. tools/bolt.diy/app/types/design-scheme.ts +93 -0
  326. tools/bolt.diy/app/types/global.d.ts +13 -0
  327. tools/bolt.diy/app/types/mandate.ts +333 -0
  328. tools/bolt.diy/app/types/model.ts +25 -0
  329. tools/bolt.diy/app/types/netlify.ts +94 -0
  330. tools/bolt.diy/app/types/supabase.ts +54 -0
  331. tools/bolt.diy/app/types/template.ts +8 -0
  332. tools/bolt.diy/app/types/terminal.ts +9 -0
  333. tools/bolt.diy/app/types/theme.ts +1 -0
  334. tools/bolt.diy/app/types/vercel.ts +67 -0
  335. tools/bolt.diy/app/utils/buffer.ts +29 -0
  336. tools/bolt.diy/app/utils/classNames.ts +65 -0
  337. tools/bolt.diy/app/utils/constants.ts +147 -0
  338. tools/bolt.diy/app/utils/debounce.ts +13 -0
  339. tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
  340. tools/bolt.diy/app/utils/diff.spec.ts +11 -0
  341. tools/bolt.diy/app/utils/diff.ts +117 -0
  342. tools/bolt.diy/app/utils/easings.ts +3 -0
  343. tools/bolt.diy/app/utils/fileLocks.ts +96 -0
  344. tools/bolt.diy/app/utils/fileUtils.ts +121 -0
  345. tools/bolt.diy/app/utils/folderImport.ts +73 -0
  346. tools/bolt.diy/app/utils/formatSize.ts +12 -0
  347. tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
  348. tools/bolt.diy/app/utils/githubStats.ts +9 -0
  349. tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
  350. tools/bolt.diy/app/utils/logger.ts +162 -0
  351. tools/bolt.diy/app/utils/markdown.ts +155 -0
  352. tools/bolt.diy/app/utils/mobile.ts +4 -0
  353. tools/bolt.diy/app/utils/os.ts +4 -0
  354. tools/bolt.diy/app/utils/path.ts +19 -0
  355. tools/bolt.diy/app/utils/projectCommands.ts +197 -0
  356. tools/bolt.diy/app/utils/promises.ts +19 -0
  357. tools/bolt.diy/app/utils/react.ts +6 -0
  358. tools/bolt.diy/app/utils/sampler.ts +49 -0
  359. tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
  360. tools/bolt.diy/app/utils/shell.ts +384 -0
  361. tools/bolt.diy/app/utils/stacktrace.ts +27 -0
  362. tools/bolt.diy/app/utils/stripIndent.ts +23 -0
  363. tools/bolt.diy/app/utils/terminal.ts +11 -0
  364. tools/bolt.diy/app/utils/unreachable.ts +3 -0
  365. tools/bolt.diy/app/vite-env.d.ts +2 -0
  366. tools/bolt.diy/assets/entitlements.mac.plist +25 -0
  367. tools/bolt.diy/assets/icons/icon.icns +0 -0
  368. tools/bolt.diy/assets/icons/icon.ico +0 -0
  369. tools/bolt.diy/assets/icons/icon.png +0 -0
  370. tools/bolt.diy/bindings.js +78 -0
  371. tools/bolt.diy/bindings.sh +33 -0
  372. tools/bolt.diy/docker-compose.yaml +145 -0
  373. tools/bolt.diy/electron/main/index.ts +201 -0
  374. tools/bolt.diy/electron/main/tsconfig.json +30 -0
  375. tools/bolt.diy/electron/main/ui/menu.ts +29 -0
  376. tools/bolt.diy/electron/main/ui/window.ts +54 -0
  377. tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
  378. tools/bolt.diy/electron/main/utils/constants.ts +4 -0
  379. tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
  380. tools/bolt.diy/electron/main/utils/reload.ts +35 -0
  381. tools/bolt.diy/electron/main/utils/serve.ts +71 -0
  382. tools/bolt.diy/electron/main/utils/store.ts +3 -0
  383. tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
  384. tools/bolt.diy/electron/main/vite.config.ts +44 -0
  385. tools/bolt.diy/electron/preload/index.ts +22 -0
  386. tools/bolt.diy/electron/preload/tsconfig.json +7 -0
  387. tools/bolt.diy/electron/preload/vite.config.ts +31 -0
  388. tools/bolt.diy/electron-builder.yml +64 -0
  389. tools/bolt.diy/electron-update.yml +4 -0
  390. tools/bolt.diy/eslint.config.mjs +57 -0
  391. tools/bolt.diy/functions/[[path]].ts +12 -0
  392. tools/bolt.diy/icons/angular.svg +1 -0
  393. tools/bolt.diy/icons/astro.svg +8 -0
  394. tools/bolt.diy/icons/chat.svg +1 -0
  395. tools/bolt.diy/icons/expo-brand.svg +1 -0
  396. tools/bolt.diy/icons/expo.svg +4 -0
  397. tools/bolt.diy/icons/logo-text.svg +1 -0
  398. tools/bolt.diy/icons/logo.svg +4 -0
  399. tools/bolt.diy/icons/mcp.svg +1 -0
  400. tools/bolt.diy/icons/nativescript.svg +1 -0
  401. tools/bolt.diy/icons/netlify.svg +10 -0
  402. tools/bolt.diy/icons/nextjs.svg +1 -0
  403. tools/bolt.diy/icons/nuxt.svg +1 -0
  404. tools/bolt.diy/icons/qwik.svg +1 -0
  405. tools/bolt.diy/icons/react.svg +1 -0
  406. tools/bolt.diy/icons/remix.svg +24 -0
  407. tools/bolt.diy/icons/remotion.svg +1 -0
  408. tools/bolt.diy/icons/shadcn.svg +21 -0
  409. tools/bolt.diy/icons/slidev.svg +60 -0
  410. tools/bolt.diy/icons/solidjs.svg +1 -0
  411. tools/bolt.diy/icons/stars.svg +1 -0
  412. tools/bolt.diy/icons/svelte.svg +1 -0
  413. tools/bolt.diy/icons/typescript.svg +1 -0
  414. tools/bolt.diy/icons/vite.svg +1 -0
  415. tools/bolt.diy/icons/vue.svg +1 -0
  416. tools/bolt.diy/load-context.ts +9 -0
  417. tools/bolt.diy/notarize.cjs +31 -0
  418. tools/bolt.diy/package.json +218 -0
  419. tools/bolt.diy/playwright.config.preview.ts +35 -0
  420. tools/bolt.diy/pre-start.cjs +26 -0
  421. tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
  422. tools/bolt.diy/public/apple-touch-icon.png +0 -0
  423. tools/bolt.diy/public/favicon.ico +0 -0
  424. tools/bolt.diy/public/favicon.svg +4 -0
  425. tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
  426. tools/bolt.diy/public/icons/Anthropic.svg +4 -0
  427. tools/bolt.diy/public/icons/Cohere.svg +4 -0
  428. tools/bolt.diy/public/icons/Deepseek.svg +5 -0
  429. tools/bolt.diy/public/icons/Default.svg +4 -0
  430. tools/bolt.diy/public/icons/Google.svg +4 -0
  431. tools/bolt.diy/public/icons/Groq.svg +4 -0
  432. tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
  433. tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
  434. tools/bolt.diy/public/icons/LMStudio.svg +5 -0
  435. tools/bolt.diy/public/icons/Mistral.svg +4 -0
  436. tools/bolt.diy/public/icons/Ollama.svg +4 -0
  437. tools/bolt.diy/public/icons/OpenAI.svg +4 -0
  438. tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
  439. tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
  440. tools/bolt.diy/public/icons/Perplexity.svg +4 -0
  441. tools/bolt.diy/public/icons/Together.svg +4 -0
  442. tools/bolt.diy/public/icons/xAI.svg +5 -0
  443. tools/bolt.diy/public/inspector-script.js +292 -0
  444. tools/bolt.diy/public/logo-dark-styled.png +0 -0
  445. tools/bolt.diy/public/logo-dark.png +0 -0
  446. tools/bolt.diy/public/logo-light-styled.png +0 -0
  447. tools/bolt.diy/public/logo-light.png +0 -0
  448. tools/bolt.diy/public/logo.svg +15 -0
  449. tools/bolt.diy/public/social_preview_index.jpg +0 -0
  450. tools/bolt.diy/scripts/clean.js +45 -0
  451. tools/bolt.diy/scripts/electron-dev.mjs +181 -0
  452. tools/bolt.diy/scripts/setup-env.sh +41 -0
  453. tools/bolt.diy/scripts/update-imports.sh +7 -0
  454. tools/bolt.diy/scripts/update.sh +52 -0
  455. tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
  456. tools/bolt.diy/services/execution-governor/config.ts +42 -0
  457. tools/bolt.diy/services/execution-governor/index.ts +683 -0
  458. tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
  459. tools/bolt.diy/services/execution-governor/package.json +31 -0
  460. tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
  461. tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
  462. tools/bolt.diy/services/execution-governor/types.ts +145 -0
  463. tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
  464. tools/bolt.diy/services/headless-executor/executor.ts +210 -0
  465. tools/bolt.diy/services/headless-executor/index.ts +323 -0
  466. tools/bolt.diy/services/headless-executor/package.json +27 -0
  467. tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
  468. tools/bolt.diy/services/headless-executor/types.ts +38 -0
  469. tools/bolt.diy/test-workflows.sh +240 -0
  470. tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
  471. tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
  472. tools/bolt.diy/tests/mandates/complex.json +53 -0
  473. tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
  474. tools/bolt.diy/tests/mandates/simple.json +35 -0
  475. tools/bolt.diy/tsconfig.json +37 -0
  476. tools/bolt.diy/types/istextorbinary.d.ts +15 -0
  477. tools/bolt.diy/uno.config.ts +279 -0
  478. tools/bolt.diy/vite-electron.config.ts +76 -0
  479. tools/bolt.diy/vite.config.ts +112 -0
  480. tools/bolt.diy/worker-configuration.d.ts +22 -0
  481. tools/bolt.diy/wrangler.toml +6 -0
  482. tools/code_generator.py +461 -0
  483. tools/file_operations.py +465 -0
  484. tools/mandate_generator.py +337 -0
  485. tools/mcpClientUtils.py +1216 -0
  486. tools/sensors.py +285 -0
  487. utils/Agent_types.py +15 -0
  488. utils/AnyToStr.py +0 -0
  489. utils/HHCS.py +277 -0
  490. utils/__init__.py +30 -0
  491. utils/agent.py +3627 -0
  492. utils/aop.py +2948 -0
  493. utils/canonical.py +143 -0
  494. utils/conversation.py +1195 -0
  495. utils/doctrine_versioning +230 -0
  496. utils/formatter.py +474 -0
  497. utils/ledger.py +311 -0
  498. utils/out_types.py +16 -0
  499. utils/rollback.py +339 -0
  500. utils/router.py +929 -0
  501. utils/tui.py +1908 -0
utils/ledger.py ADDED
@@ -0,0 +1,311 @@
1
+ """Event-sourced ledger for policy engine.
2
+
3
+ This module provides a SQLite-based append-only event store for the policy engine.
4
+ The ledger serves as:
5
+ - Dataset for online learning
6
+ - Audit trail for decisions
7
+ - Replay engine for deterministic execution
8
+
9
+ All events are hashed and stored immutably (append-only).
10
+ """
11
+
12
+ import sqlite3
13
+ import json
14
+ from typing import Any, Dict, List, Optional
15
+ from datetime import datetime
16
+ from loguru import logger
17
+
18
+ from schemas.policy import LedgerEvent
19
+
20
+
21
+ class Ledger:
22
+ """SQLite-based append-only event ledger.
23
+
24
+ Schema:
25
+ events(
26
+ id INTEGER PRIMARY KEY,
27
+ type TEXT,
28
+ epoch INTEGER,
29
+ hash TEXT UNIQUE,
30
+ payload_json TEXT
31
+ )
32
+
33
+ Indexed on (epoch, type) for fast window queries.
34
+ """
35
+
36
+ def __init__(self, db_path: str):
37
+ """
38
+ Initialize ledger with SQLite database.
39
+
40
+ Args:
41
+ db_path: Path to SQLite database file
42
+ """
43
+ self.db_path = db_path
44
+ self._conn: Optional[sqlite3.Connection] = None
45
+ self._initialize_db()
46
+
47
+ def _initialize_db(self) -> None:
48
+ """Initialize database schema if it doesn't exist."""
49
+ conn = sqlite3.connect(self.db_path)
50
+ cursor = conn.cursor()
51
+
52
+ # Create events table
53
+ cursor.execute("""
54
+ CREATE TABLE IF NOT EXISTS events (
55
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
56
+ type TEXT NOT NULL,
57
+ epoch INTEGER NOT NULL,
58
+ hash TEXT UNIQUE NOT NULL,
59
+ payload_json TEXT NOT NULL,
60
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
61
+ )
62
+ """)
63
+
64
+ # Create indexes for fast queries
65
+ cursor.execute("""
66
+ CREATE INDEX IF NOT EXISTS idx_epoch_type
67
+ ON events(epoch, type)
68
+ """)
69
+
70
+ cursor.execute("""
71
+ CREATE INDEX IF NOT EXISTS idx_epoch
72
+ ON events(epoch)
73
+ """)
74
+
75
+ conn.commit()
76
+ conn.close()
77
+
78
+ def _get_connection(self) -> sqlite3.Connection:
79
+ """Get or create database connection."""
80
+ if self._conn is None:
81
+ self._conn = sqlite3.connect(self.db_path)
82
+ self._conn.row_factory = sqlite3.Row
83
+ return self._conn
84
+
85
+ def append(self, event: LedgerEvent) -> int:
86
+ """
87
+ Append an event to the ledger.
88
+
89
+ Args:
90
+ event: LedgerEvent to append
91
+
92
+ Returns:
93
+ int: Event ID
94
+
95
+ Raises:
96
+ sqlite3.IntegrityError: If hash already exists (duplicate event)
97
+ """
98
+ conn = self._get_connection()
99
+ cursor = conn.cursor()
100
+
101
+ try:
102
+ cursor.execute("""
103
+ INSERT INTO events (type, epoch, hash, payload_json)
104
+ VALUES (?, ?, ?, ?)
105
+ """, (
106
+ event.type,
107
+ event.epoch,
108
+ event.hash,
109
+ json.dumps(event.payload)
110
+ ))
111
+ conn.commit()
112
+ event_id = cursor.lastrowid
113
+ logger.debug(f"Appended event {event_id} (type={event.type}, epoch={event.epoch})")
114
+ return event_id
115
+ except sqlite3.IntegrityError as e:
116
+ if "UNIQUE constraint failed" in str(e):
117
+ logger.warning(f"Duplicate event hash {event.hash} - skipping")
118
+ # Return existing event ID
119
+ cursor.execute("SELECT id FROM events WHERE hash = ?", (event.hash,))
120
+ row = cursor.fetchone()
121
+ return row["id"] if row else -1
122
+ raise
123
+
124
+ def window(self, epoch: int, k: int, event_type: Optional[str] = None) -> List[Dict[str, Any]]:
125
+ """
126
+ Get events from the last k epochs ending at epoch.
127
+
128
+ Args:
129
+ epoch: End epoch (inclusive)
130
+ k: Number of epochs to look back
131
+ event_type: Optional event type filter
132
+
133
+ Returns:
134
+ List[Dict[str, Any]]: List of event dictionaries
135
+ """
136
+ conn = self._get_connection()
137
+ cursor = conn.cursor()
138
+
139
+ start_epoch = max(0, epoch - k + 1)
140
+
141
+ if event_type:
142
+ cursor.execute("""
143
+ SELECT * FROM events
144
+ WHERE epoch >= ? AND epoch <= ? AND type = ?
145
+ ORDER BY epoch ASC, id ASC
146
+ """, (start_epoch, epoch, event_type))
147
+ else:
148
+ cursor.execute("""
149
+ SELECT * FROM events
150
+ WHERE epoch >= ? AND epoch <= ?
151
+ ORDER BY epoch ASC, id ASC
152
+ """, (start_epoch, epoch))
153
+
154
+ rows = cursor.fetchall()
155
+ events = []
156
+ for row in rows:
157
+ events.append({
158
+ "id": row["id"],
159
+ "type": row["type"],
160
+ "epoch": row["epoch"],
161
+ "hash": row["hash"],
162
+ "payload": json.loads(row["payload_json"]),
163
+ "created_at": row["created_at"]
164
+ })
165
+
166
+ return events
167
+
168
+ def latest(self, event_type: Optional[str] = None, epoch: Optional[int] = None) -> Optional[Dict[str, Any]]:
169
+ """
170
+ Get the latest event (optionally filtered by type and epoch).
171
+
172
+ Args:
173
+ event_type: Optional event type filter
174
+ epoch: Optional epoch filter
175
+
176
+ Returns:
177
+ Optional[Dict[str, Any]]: Latest event or None
178
+ """
179
+ conn = self._get_connection()
180
+ cursor = conn.cursor()
181
+
182
+ if event_type and epoch is not None:
183
+ cursor.execute("""
184
+ SELECT * FROM events
185
+ WHERE type = ? AND epoch = ?
186
+ ORDER BY id DESC
187
+ LIMIT 1
188
+ """, (event_type, epoch))
189
+ elif event_type:
190
+ cursor.execute("""
191
+ SELECT * FROM events
192
+ WHERE type = ?
193
+ ORDER BY epoch DESC, id DESC
194
+ LIMIT 1
195
+ """, (event_type,))
196
+ elif epoch is not None:
197
+ cursor.execute("""
198
+ SELECT * FROM events
199
+ WHERE epoch = ?
200
+ ORDER BY id DESC
201
+ LIMIT 1
202
+ """, (epoch,))
203
+ else:
204
+ cursor.execute("""
205
+ SELECT * FROM events
206
+ ORDER BY epoch DESC, id DESC
207
+ LIMIT 1
208
+ """)
209
+
210
+ row = cursor.fetchone()
211
+ if row:
212
+ return {
213
+ "id": row["id"],
214
+ "type": row["type"],
215
+ "epoch": row["epoch"],
216
+ "hash": row["hash"],
217
+ "payload": json.loads(row["payload_json"]),
218
+ "created_at": row["created_at"]
219
+ }
220
+ return None
221
+
222
+ def iter_range(
223
+ self,
224
+ t0: int,
225
+ t1: int,
226
+ event_type: Optional[str] = None
227
+ ) -> List[Dict[str, Any]]:
228
+ """
229
+ Iterate over events in epoch range [t0, t1] (inclusive).
230
+
231
+ Args:
232
+ t0: Start epoch (inclusive)
233
+ t1: End epoch (inclusive)
234
+ event_type: Optional event type filter
235
+
236
+ Returns:
237
+ List[Dict[str, Any]]: List of event dictionaries
238
+ """
239
+ conn = self._get_connection()
240
+ cursor = conn.cursor()
241
+
242
+ if event_type:
243
+ cursor.execute("""
244
+ SELECT * FROM events
245
+ WHERE epoch >= ? AND epoch <= ? AND type = ?
246
+ ORDER BY epoch ASC, id ASC
247
+ """, (t0, t1, event_type))
248
+ else:
249
+ cursor.execute("""
250
+ SELECT * FROM events
251
+ WHERE epoch >= ? AND epoch <= ?
252
+ ORDER BY epoch ASC, id ASC
253
+ """, (t0, t1))
254
+
255
+ rows = cursor.fetchall()
256
+ events = []
257
+ for row in rows:
258
+ events.append({
259
+ "id": row["id"],
260
+ "type": row["type"],
261
+ "epoch": row["epoch"],
262
+ "hash": row["hash"],
263
+ "payload": json.loads(row["payload_json"]),
264
+ "created_at": row["created_at"]
265
+ })
266
+
267
+ return events
268
+
269
+ def compute_deltas(self, epoch: int) -> Dict[str, float]:
270
+ """
271
+ Compute feature deltas between observation and outcome at epoch t.
272
+
273
+ Args:
274
+ epoch: Epoch to compute deltas for
275
+
276
+ Returns:
277
+ Dict[str, float]: Dictionary mapping metric names to deltas
278
+ """
279
+ obs = self.latest(event_type="observation", epoch=epoch)
280
+ outcome = self.latest(event_type="outcome", epoch=epoch)
281
+
282
+ if not obs or not outcome:
283
+ return {}
284
+
285
+ obs_metrics = obs["payload"].get("metrics", {})
286
+ outcome_metrics = outcome["payload"].get("metrics", {})
287
+
288
+ deltas = {}
289
+ all_metrics = set(obs_metrics.keys()) | set(outcome_metrics.keys())
290
+
291
+ for metric in all_metrics:
292
+ obs_val = obs_metrics.get(metric, 0.0)
293
+ outcome_val = outcome_metrics.get(metric, 0.0)
294
+ deltas[metric] = outcome_val - obs_val
295
+
296
+ return deltas
297
+
298
+ def close(self) -> None:
299
+ """Close database connection."""
300
+ if self._conn:
301
+ self._conn.close()
302
+ self._conn = None
303
+
304
+ def __enter__(self):
305
+ """Context manager entry."""
306
+ return self
307
+
308
+ def __exit__(self, exc_type, exc_val, exc_tb):
309
+ """Context manager exit."""
310
+ self.close()
311
+
utils/out_types.py ADDED
@@ -0,0 +1,16 @@
1
+ """
2
+ Output type definitions for history and conversation formatting.
3
+
4
+ Defines type literals for specifying output formats when extracting
5
+ conversation history or agent responses.
6
+ """
7
+
8
+ from typing import Literal
9
+
10
+ HistoryOutputType = Literal[
11
+ "list", "dict", "dictionary", "string", "str", "final", "last",
12
+ "json", "all", "yaml", "xml", "dict-all-except-first",
13
+ "str-all-except-first", "basemodel", "dict-final", "list-final"
14
+ ]
15
+
16
+ OutputType = HistoryOutputType
utils/rollback.py ADDED
@@ -0,0 +1,339 @@
1
+ """Rollback system for intervention recovery.
2
+
3
+ Provides checkpoint creation, intervention recording, and rollback
4
+ execution for recovering from failed interventions.
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional
8
+ from datetime import datetime, timezone
9
+ import sqlite3
10
+ import json
11
+ import uuid
12
+ from loguru import logger
13
+
14
+ from schemas.policy import InterventionSpec
15
+
16
+
17
+ class RollbackManager:
18
+ """Rollback manager for intervention recovery.
19
+
20
+ Features:
21
+ - State checkpoint creation
22
+ - Intervention recording with results
23
+ - Rollback execution (reverse interventions)
24
+ - Checkpoint restoration
25
+ - Time-based retention
26
+ """
27
+
28
+ def __init__(self, db_path: str = ":memory:", retention_days: int = 7):
29
+ """
30
+ Initialize rollback manager.
31
+
32
+ Args:
33
+ db_path: Path to SQLite database (or ":memory:" for in-memory)
34
+ retention_days: Number of days to retain checkpoints
35
+ """
36
+ self.db_path = db_path
37
+ self.retention_days = retention_days
38
+ self.conn = sqlite3.connect(db_path)
39
+ self._init_db()
40
+
41
+ def _init_db(self) -> None:
42
+ """Initialize database schema."""
43
+ cursor = self.conn.cursor()
44
+
45
+ # Checkpoints table
46
+ cursor.execute("""
47
+ CREATE TABLE IF NOT EXISTS checkpoints (
48
+ checkpoint_id TEXT PRIMARY KEY,
49
+ epoch INTEGER NOT NULL,
50
+ state_json TEXT NOT NULL,
51
+ created_at TIMESTAMP NOT NULL
52
+ )
53
+ """)
54
+
55
+ # Interventions table
56
+ cursor.execute("""
57
+ CREATE TABLE IF NOT EXISTS interventions (
58
+ intervention_id TEXT PRIMARY KEY,
59
+ checkpoint_id TEXT,
60
+ epoch INTEGER NOT NULL,
61
+ lever_id TEXT NOT NULL,
62
+ parameters_json TEXT NOT NULL,
63
+ result_json TEXT,
64
+ rollback_descriptor_json TEXT,
65
+ created_at TIMESTAMP NOT NULL,
66
+ FOREIGN KEY (checkpoint_id) REFERENCES checkpoints(checkpoint_id)
67
+ )
68
+ """)
69
+
70
+ # Rollback history table
71
+ cursor.execute("""
72
+ CREATE TABLE IF NOT EXISTS rollback_history (
73
+ rollback_id TEXT PRIMARY KEY,
74
+ epoch INTEGER NOT NULL,
75
+ n_steps INTEGER NOT NULL,
76
+ intervention_ids TEXT NOT NULL,
77
+ created_at TIMESTAMP NOT NULL
78
+ )
79
+ """)
80
+
81
+ self.conn.commit()
82
+
83
+ def create_checkpoint(self, epoch: int, state: Dict[str, Any]) -> str:
84
+ """
85
+ Create a state checkpoint.
86
+
87
+ Args:
88
+ epoch: Epoch number
89
+ state: State dictionary to checkpoint
90
+
91
+ Returns:
92
+ str: Checkpoint ID
93
+ """
94
+ checkpoint_id = str(uuid.uuid4())
95
+ state_json = json.dumps(state)
96
+ created_at = datetime.now(timezone.utc).isoformat()
97
+
98
+ cursor = self.conn.cursor()
99
+ cursor.execute("""
100
+ INSERT INTO checkpoints (checkpoint_id, epoch, state_json, created_at)
101
+ VALUES (?, ?, ?, ?)
102
+ """, (checkpoint_id, epoch, state_json, created_at))
103
+ self.conn.commit()
104
+
105
+ logger.info(f"Created checkpoint {checkpoint_id} for epoch {epoch}")
106
+
107
+ # Clean up old checkpoints
108
+ self._cleanup_old_checkpoints()
109
+
110
+ return checkpoint_id
111
+
112
+ def record_intervention(
113
+ self,
114
+ epoch: int,
115
+ intervention: InterventionSpec,
116
+ result: Optional[Dict[str, Any]] = None,
117
+ checkpoint_id: Optional[str] = None
118
+ ) -> str:
119
+ """
120
+ Record an intervention with its result.
121
+
122
+ Args:
123
+ epoch: Epoch number
124
+ intervention: Intervention specification
125
+ result: Optional execution result
126
+ checkpoint_id: Optional checkpoint ID associated with this intervention
127
+
128
+ Returns:
129
+ str: Intervention ID
130
+ """
131
+ intervention_id = str(uuid.uuid4())
132
+ parameters_json = json.dumps(intervention.parameters)
133
+ result_json = json.dumps(result) if result else None
134
+ rollback_descriptor_json = json.dumps(intervention.rollback_descriptor) if intervention.rollback_descriptor else None
135
+ created_at = datetime.now(timezone.utc).isoformat()
136
+
137
+ cursor = self.conn.cursor()
138
+ cursor.execute("""
139
+ INSERT INTO interventions (
140
+ intervention_id, checkpoint_id, epoch, lever_id,
141
+ parameters_json, result_json, rollback_descriptor_json, created_at
142
+ )
143
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
144
+ """, (
145
+ intervention_id, checkpoint_id, epoch, intervention.lever_id,
146
+ parameters_json, result_json, rollback_descriptor_json, created_at
147
+ ))
148
+ self.conn.commit()
149
+
150
+ logger.debug(f"Recorded intervention {intervention_id} for epoch {epoch}")
151
+
152
+ return intervention_id
153
+
154
+ def rollback(
155
+ self,
156
+ epoch: int,
157
+ n_steps: int,
158
+ actuator_registry: Optional[Any] = None
159
+ ) -> List[str]:
160
+ """
161
+ Rollback last N interventions.
162
+
163
+ Args:
164
+ epoch: Current epoch
165
+ n_steps: Number of steps to rollback
166
+ actuator_registry: Optional actuator registry for executing rollbacks
167
+
168
+ Returns:
169
+ List[str]: List of intervention IDs that were rolled back
170
+ """
171
+ cursor = self.conn.cursor()
172
+
173
+ # Get last N interventions (most recent first)
174
+ cursor.execute("""
175
+ SELECT intervention_id, lever_id, parameters_json, rollback_descriptor_json
176
+ FROM interventions
177
+ WHERE epoch <= ?
178
+ ORDER BY created_at DESC
179
+ LIMIT ?
180
+ """, (epoch, n_steps))
181
+
182
+ interventions = cursor.fetchall()
183
+
184
+ if not interventions:
185
+ logger.warning(f"No interventions found to rollback (epoch {epoch}, n_steps {n_steps})")
186
+ return []
187
+
188
+ rolled_back_ids = []
189
+
190
+ # Execute rollbacks in reverse order (oldest first)
191
+ for intervention_id, lever_id, parameters_json, rollback_descriptor_json in reversed(interventions):
192
+ try:
193
+ if rollback_descriptor_json:
194
+ rollback_descriptor = json.loads(rollback_descriptor_json)
195
+
196
+ # Execute rollback via actuator if available
197
+ if actuator_registry:
198
+ actuator = actuator_registry.get_actuator_for_lever(lever_id)
199
+ if actuator:
200
+ success = actuator.rollback(rollback_descriptor)
201
+ if success:
202
+ logger.info(f"Rolled back intervention {intervention_id}")
203
+ else:
204
+ logger.warning(f"Rollback failed for intervention {intervention_id}")
205
+ else:
206
+ logger.warning(f"No actuator found for lever {lever_id}")
207
+ else:
208
+ logger.info(f"Rollback descriptor for {intervention_id}: {rollback_descriptor}")
209
+
210
+ rolled_back_ids.append(intervention_id)
211
+ except Exception as e:
212
+ logger.error(f"Error rolling back intervention {intervention_id}: {e}")
213
+
214
+ # Record rollback in history
215
+ rollback_id = str(uuid.uuid4())
216
+ intervention_ids_json = json.dumps(rolled_back_ids)
217
+ created_at = datetime.now(timezone.utc).isoformat()
218
+
219
+ cursor.execute("""
220
+ INSERT INTO rollback_history (rollback_id, epoch, n_steps, intervention_ids, created_at)
221
+ VALUES (?, ?, ?, ?, ?)
222
+ """, (rollback_id, epoch, n_steps, intervention_ids_json, created_at))
223
+ self.conn.commit()
224
+
225
+ logger.info(f"Rolled back {len(rolled_back_ids)} interventions")
226
+
227
+ return rolled_back_ids
228
+
229
+ def restore_checkpoint(self, checkpoint_id: str) -> Optional[Dict[str, Any]]:
230
+ """
231
+ Restore state from checkpoint.
232
+
233
+ Args:
234
+ checkpoint_id: Checkpoint ID to restore
235
+
236
+ Returns:
237
+ Dict[str, Any]: Restored state or None if not found
238
+ """
239
+ cursor = self.conn.cursor()
240
+ cursor.execute("""
241
+ SELECT state_json FROM checkpoints WHERE checkpoint_id = ?
242
+ """, (checkpoint_id,))
243
+
244
+ row = cursor.fetchone()
245
+ if row:
246
+ state = json.loads(row[0])
247
+ logger.info(f"Restored checkpoint {checkpoint_id}")
248
+ return state
249
+ else:
250
+ logger.warning(f"Checkpoint {checkpoint_id} not found")
251
+ return None
252
+
253
+ def get_latest_checkpoint(self, epoch: Optional[int] = None) -> Optional[str]:
254
+ """
255
+ Get the latest checkpoint ID.
256
+
257
+ Args:
258
+ epoch: Optional epoch to filter by (get latest before or at this epoch)
259
+
260
+ Returns:
261
+ str: Checkpoint ID or None
262
+ """
263
+ cursor = self.conn.cursor()
264
+
265
+ if epoch is not None:
266
+ cursor.execute("""
267
+ SELECT checkpoint_id FROM checkpoints
268
+ WHERE epoch <= ?
269
+ ORDER BY created_at DESC
270
+ LIMIT 1
271
+ """, (epoch,))
272
+ else:
273
+ cursor.execute("""
274
+ SELECT checkpoint_id FROM checkpoints
275
+ ORDER BY created_at DESC
276
+ LIMIT 1
277
+ """)
278
+
279
+ row = cursor.fetchone()
280
+ return row[0] if row else None
281
+
282
+ def get_rollback_history(self, limit: int = 100) -> List[Dict[str, Any]]:
283
+ """
284
+ Get rollback history.
285
+
286
+ Args:
287
+ limit: Maximum number of records to return
288
+
289
+ Returns:
290
+ List[Dict[str, Any]]: Rollback history records
291
+ """
292
+ cursor = self.conn.cursor()
293
+ cursor.execute("""
294
+ SELECT rollback_id, epoch, n_steps, intervention_ids, created_at
295
+ FROM rollback_history
296
+ ORDER BY created_at DESC
297
+ LIMIT ?
298
+ """, (limit,))
299
+
300
+ rows = cursor.fetchall()
301
+ return [
302
+ {
303
+ "rollback_id": row[0],
304
+ "epoch": row[1],
305
+ "n_steps": row[2],
306
+ "intervention_ids": json.loads(row[3]),
307
+ "created_at": row[4]
308
+ }
309
+ for row in rows
310
+ ]
311
+
312
+ def _cleanup_old_checkpoints(self) -> None:
313
+ """Clean up checkpoints older than retention period."""
314
+ cutoff = datetime.now(timezone.utc).timestamp() - (self.retention_days * 86400)
315
+ cutoff_iso = datetime.fromtimestamp(cutoff, tz=timezone.utc).isoformat()
316
+
317
+ cursor = self.conn.cursor()
318
+ cursor.execute("""
319
+ DELETE FROM checkpoints WHERE created_at < ?
320
+ """, (cutoff_iso,))
321
+
322
+ deleted = cursor.rowcount
323
+ if deleted > 0:
324
+ logger.info(f"Cleaned up {deleted} old checkpoints")
325
+
326
+ self.conn.commit()
327
+
328
+ def close(self) -> None:
329
+ """Close database connection."""
330
+ self.conn.close()
331
+
332
+ def __enter__(self):
333
+ """Context manager entry."""
334
+ return self
335
+
336
+ def __exit__(self, exc_type, exc_val, exc_tb):
337
+ """Context manager exit."""
338
+ self.close()
339
+