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.
- .github/ISSUE_TEMPLATE/bug_report.md +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +41 -0
- .github/PULL_REQUEST_TEMPLATE.md +20 -0
- .github/workflows/publish-manual.yml +61 -0
- .github/workflows/publish.yml +64 -0
- .gitignore +214 -0
- CRCA.py +4156 -0
- LICENSE +201 -0
- MANIFEST.in +43 -0
- PKG-INFO +5035 -0
- README.md +4959 -0
- __init__.py +17 -0
- branches/CRCA-Q.py +2728 -0
- branches/crca_cg/corposwarm.py +9065 -0
- branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
- branches/crca_cg/package.json +5 -0
- branches/crca_cg/test_bolt_integration.py +446 -0
- branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
- branches/crca_cg/test_new_features.py +163 -0
- branches/crca_sd/__init__.py +149 -0
- branches/crca_sd/crca_sd_core.py +770 -0
- branches/crca_sd/crca_sd_governance.py +1325 -0
- branches/crca_sd/crca_sd_mpc.py +1130 -0
- branches/crca_sd/crca_sd_realtime.py +1844 -0
- branches/crca_sd/crca_sd_tui.py +1133 -0
- crca-1.4.0.dist-info/METADATA +5035 -0
- crca-1.4.0.dist-info/RECORD +501 -0
- crca-1.4.0.dist-info/WHEEL +4 -0
- crca-1.4.0.dist-info/licenses/LICENSE +201 -0
- docs/CRCA-Q.md +2333 -0
- examples/config.yaml.example +25 -0
- examples/crca_sd_example.py +513 -0
- examples/data_broker_example.py +294 -0
- examples/logistics_corporation.py +861 -0
- examples/palantir_example.py +299 -0
- examples/policy_bench.py +934 -0
- examples/pridnestrovia-sd.py +705 -0
- examples/pridnestrovia_realtime.py +1902 -0
- prompts/__init__.py +10 -0
- prompts/default_crca.py +101 -0
- pyproject.toml +151 -0
- requirements.txt +76 -0
- schemas/__init__.py +43 -0
- schemas/mcpSchemas.py +51 -0
- schemas/policy.py +458 -0
- templates/__init__.py +38 -0
- templates/base_specialized_agent.py +195 -0
- templates/drift_detection.py +325 -0
- templates/examples/causal_agent_template.py +309 -0
- templates/examples/drag_drop_example.py +213 -0
- templates/examples/logistics_agent_template.py +207 -0
- templates/examples/trading_agent_template.py +206 -0
- templates/feature_mixins.py +253 -0
- templates/graph_management.py +442 -0
- templates/llm_integration.py +194 -0
- templates/module_registry.py +276 -0
- templates/mpc_planner.py +280 -0
- templates/policy_loop.py +1168 -0
- templates/prediction_framework.py +448 -0
- templates/statistical_methods.py +778 -0
- tests/sanity.yml +31 -0
- tests/sanity_check +406 -0
- tests/test_core.py +47 -0
- tests/test_crca_excel.py +166 -0
- tests/test_crca_sd.py +780 -0
- tests/test_data_broker.py +424 -0
- tests/test_palantir.py +349 -0
- tools/__init__.py +38 -0
- tools/actuators.py +437 -0
- tools/bolt.diy/Dockerfile +103 -0
- tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
- tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
- tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
- tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
- tools/bolt.diy/app/components/@settings/index.ts +12 -0
- tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
- tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
- tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
- tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
- tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
- tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
- tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
- tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
- tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
- tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
- tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
- tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
- tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
- tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
- tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
- tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
- tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
- tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
- tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
- tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
- tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
- tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
- tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
- tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
- tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
- tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
- tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
- tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
- tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
- tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
- tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
- tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
- tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
- tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
- tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
- tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
- tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
- tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
- tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
- tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
- tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
- tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
- tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
- tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
- tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
- tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
- tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
- tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
- tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
- tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
- tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
- tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
- tools/bolt.diy/app/components/header/Header.tsx +42 -0
- tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
- tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
- tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
- tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
- tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
- tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
- tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
- tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
- tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
- tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
- tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
- tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
- tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
- tools/bolt.diy/app/components/txt +1 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
- tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
- tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
- tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
- tools/bolt.diy/app/components/ui/Button.tsx +46 -0
- tools/bolt.diy/app/components/ui/Card.tsx +55 -0
- tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
- tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
- tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
- tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
- tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
- tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
- tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
- tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
- tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
- tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
- tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
- tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
- tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
- tools/bolt.diy/app/components/ui/Input.tsx +22 -0
- tools/bolt.diy/app/components/ui/Label.tsx +20 -0
- tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
- tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
- tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
- tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
- tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
- tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
- tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
- tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
- tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
- tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
- tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
- tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
- tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
- tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
- tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
- tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
- tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
- tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
- tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
- tools/bolt.diy/app/components/ui/index.ts +38 -0
- tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
- tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
- tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
- tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
- tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
- tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
- tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
- tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
- tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
- tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
- tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
- tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
- tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
- tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
- tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
- tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
- tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
- tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
- tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
- tools/bolt.diy/app/entry.client.tsx +7 -0
- tools/bolt.diy/app/entry.server.tsx +80 -0
- tools/bolt.diy/app/root.tsx +156 -0
- tools/bolt.diy/app/routes/_index.tsx +175 -0
- tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
- tools/bolt.diy/app/routes/api.chat.ts +463 -0
- tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
- tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
- tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
- tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
- tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
- tools/bolt.diy/app/routes/api.git-info.ts +69 -0
- tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
- tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
- tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
- tools/bolt.diy/app/routes/api.github-template.ts +242 -0
- tools/bolt.diy/app/routes/api.github-user.ts +287 -0
- tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
- tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
- tools/bolt.diy/app/routes/api.health.ts +8 -0
- tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
- tools/bolt.diy/app/routes/api.mandate.ts +351 -0
- tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
- tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
- tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
- tools/bolt.diy/app/routes/api.models.ts +90 -0
- tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
- tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
- tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
- tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
- tools/bolt.diy/app/routes/api.supabase.ts +56 -0
- tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
- tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
- tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
- tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
- tools/bolt.diy/app/routes/api.update.ts +21 -0
- tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
- tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
- tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
- tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
- tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
- tools/bolt.diy/app/routes/git.tsx +25 -0
- tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
- tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
- tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
- tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
- tools/bolt.diy/app/styles/animations.scss +49 -0
- tools/bolt.diy/app/styles/components/code.scss +9 -0
- tools/bolt.diy/app/styles/components/editor.scss +135 -0
- tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
- tools/bolt.diy/app/styles/components/terminal.scss +3 -0
- tools/bolt.diy/app/styles/components/toast.scss +23 -0
- tools/bolt.diy/app/styles/diff-view.css +72 -0
- tools/bolt.diy/app/styles/index.scss +73 -0
- tools/bolt.diy/app/styles/variables.scss +255 -0
- tools/bolt.diy/app/styles/z-index.scss +37 -0
- tools/bolt.diy/app/types/GitHub.ts +182 -0
- tools/bolt.diy/app/types/GitLab.ts +103 -0
- tools/bolt.diy/app/types/actions.ts +85 -0
- tools/bolt.diy/app/types/artifact.ts +5 -0
- tools/bolt.diy/app/types/context.ts +26 -0
- tools/bolt.diy/app/types/design-scheme.ts +93 -0
- tools/bolt.diy/app/types/global.d.ts +13 -0
- tools/bolt.diy/app/types/mandate.ts +333 -0
- tools/bolt.diy/app/types/model.ts +25 -0
- tools/bolt.diy/app/types/netlify.ts +94 -0
- tools/bolt.diy/app/types/supabase.ts +54 -0
- tools/bolt.diy/app/types/template.ts +8 -0
- tools/bolt.diy/app/types/terminal.ts +9 -0
- tools/bolt.diy/app/types/theme.ts +1 -0
- tools/bolt.diy/app/types/vercel.ts +67 -0
- tools/bolt.diy/app/utils/buffer.ts +29 -0
- tools/bolt.diy/app/utils/classNames.ts +65 -0
- tools/bolt.diy/app/utils/constants.ts +147 -0
- tools/bolt.diy/app/utils/debounce.ts +13 -0
- tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
- tools/bolt.diy/app/utils/diff.spec.ts +11 -0
- tools/bolt.diy/app/utils/diff.ts +117 -0
- tools/bolt.diy/app/utils/easings.ts +3 -0
- tools/bolt.diy/app/utils/fileLocks.ts +96 -0
- tools/bolt.diy/app/utils/fileUtils.ts +121 -0
- tools/bolt.diy/app/utils/folderImport.ts +73 -0
- tools/bolt.diy/app/utils/formatSize.ts +12 -0
- tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
- tools/bolt.diy/app/utils/githubStats.ts +9 -0
- tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
- tools/bolt.diy/app/utils/logger.ts +162 -0
- tools/bolt.diy/app/utils/markdown.ts +155 -0
- tools/bolt.diy/app/utils/mobile.ts +4 -0
- tools/bolt.diy/app/utils/os.ts +4 -0
- tools/bolt.diy/app/utils/path.ts +19 -0
- tools/bolt.diy/app/utils/projectCommands.ts +197 -0
- tools/bolt.diy/app/utils/promises.ts +19 -0
- tools/bolt.diy/app/utils/react.ts +6 -0
- tools/bolt.diy/app/utils/sampler.ts +49 -0
- tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
- tools/bolt.diy/app/utils/shell.ts +384 -0
- tools/bolt.diy/app/utils/stacktrace.ts +27 -0
- tools/bolt.diy/app/utils/stripIndent.ts +23 -0
- tools/bolt.diy/app/utils/terminal.ts +11 -0
- tools/bolt.diy/app/utils/unreachable.ts +3 -0
- tools/bolt.diy/app/vite-env.d.ts +2 -0
- tools/bolt.diy/assets/entitlements.mac.plist +25 -0
- tools/bolt.diy/assets/icons/icon.icns +0 -0
- tools/bolt.diy/assets/icons/icon.ico +0 -0
- tools/bolt.diy/assets/icons/icon.png +0 -0
- tools/bolt.diy/bindings.js +78 -0
- tools/bolt.diy/bindings.sh +33 -0
- tools/bolt.diy/docker-compose.yaml +145 -0
- tools/bolt.diy/electron/main/index.ts +201 -0
- tools/bolt.diy/electron/main/tsconfig.json +30 -0
- tools/bolt.diy/electron/main/ui/menu.ts +29 -0
- tools/bolt.diy/electron/main/ui/window.ts +54 -0
- tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
- tools/bolt.diy/electron/main/utils/constants.ts +4 -0
- tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
- tools/bolt.diy/electron/main/utils/reload.ts +35 -0
- tools/bolt.diy/electron/main/utils/serve.ts +71 -0
- tools/bolt.diy/electron/main/utils/store.ts +3 -0
- tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
- tools/bolt.diy/electron/main/vite.config.ts +44 -0
- tools/bolt.diy/electron/preload/index.ts +22 -0
- tools/bolt.diy/electron/preload/tsconfig.json +7 -0
- tools/bolt.diy/electron/preload/vite.config.ts +31 -0
- tools/bolt.diy/electron-builder.yml +64 -0
- tools/bolt.diy/electron-update.yml +4 -0
- tools/bolt.diy/eslint.config.mjs +57 -0
- tools/bolt.diy/functions/[[path]].ts +12 -0
- tools/bolt.diy/icons/angular.svg +1 -0
- tools/bolt.diy/icons/astro.svg +8 -0
- tools/bolt.diy/icons/chat.svg +1 -0
- tools/bolt.diy/icons/expo-brand.svg +1 -0
- tools/bolt.diy/icons/expo.svg +4 -0
- tools/bolt.diy/icons/logo-text.svg +1 -0
- tools/bolt.diy/icons/logo.svg +4 -0
- tools/bolt.diy/icons/mcp.svg +1 -0
- tools/bolt.diy/icons/nativescript.svg +1 -0
- tools/bolt.diy/icons/netlify.svg +10 -0
- tools/bolt.diy/icons/nextjs.svg +1 -0
- tools/bolt.diy/icons/nuxt.svg +1 -0
- tools/bolt.diy/icons/qwik.svg +1 -0
- tools/bolt.diy/icons/react.svg +1 -0
- tools/bolt.diy/icons/remix.svg +24 -0
- tools/bolt.diy/icons/remotion.svg +1 -0
- tools/bolt.diy/icons/shadcn.svg +21 -0
- tools/bolt.diy/icons/slidev.svg +60 -0
- tools/bolt.diy/icons/solidjs.svg +1 -0
- tools/bolt.diy/icons/stars.svg +1 -0
- tools/bolt.diy/icons/svelte.svg +1 -0
- tools/bolt.diy/icons/typescript.svg +1 -0
- tools/bolt.diy/icons/vite.svg +1 -0
- tools/bolt.diy/icons/vue.svg +1 -0
- tools/bolt.diy/load-context.ts +9 -0
- tools/bolt.diy/notarize.cjs +31 -0
- tools/bolt.diy/package.json +218 -0
- tools/bolt.diy/playwright.config.preview.ts +35 -0
- tools/bolt.diy/pre-start.cjs +26 -0
- tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
- tools/bolt.diy/public/apple-touch-icon.png +0 -0
- tools/bolt.diy/public/favicon.ico +0 -0
- tools/bolt.diy/public/favicon.svg +4 -0
- tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
- tools/bolt.diy/public/icons/Anthropic.svg +4 -0
- tools/bolt.diy/public/icons/Cohere.svg +4 -0
- tools/bolt.diy/public/icons/Deepseek.svg +5 -0
- tools/bolt.diy/public/icons/Default.svg +4 -0
- tools/bolt.diy/public/icons/Google.svg +4 -0
- tools/bolt.diy/public/icons/Groq.svg +4 -0
- tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
- tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
- tools/bolt.diy/public/icons/LMStudio.svg +5 -0
- tools/bolt.diy/public/icons/Mistral.svg +4 -0
- tools/bolt.diy/public/icons/Ollama.svg +4 -0
- tools/bolt.diy/public/icons/OpenAI.svg +4 -0
- tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
- tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
- tools/bolt.diy/public/icons/Perplexity.svg +4 -0
- tools/bolt.diy/public/icons/Together.svg +4 -0
- tools/bolt.diy/public/icons/xAI.svg +5 -0
- tools/bolt.diy/public/inspector-script.js +292 -0
- tools/bolt.diy/public/logo-dark-styled.png +0 -0
- tools/bolt.diy/public/logo-dark.png +0 -0
- tools/bolt.diy/public/logo-light-styled.png +0 -0
- tools/bolt.diy/public/logo-light.png +0 -0
- tools/bolt.diy/public/logo.svg +15 -0
- tools/bolt.diy/public/social_preview_index.jpg +0 -0
- tools/bolt.diy/scripts/clean.js +45 -0
- tools/bolt.diy/scripts/electron-dev.mjs +181 -0
- tools/bolt.diy/scripts/setup-env.sh +41 -0
- tools/bolt.diy/scripts/update-imports.sh +7 -0
- tools/bolt.diy/scripts/update.sh +52 -0
- tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
- tools/bolt.diy/services/execution-governor/config.ts +42 -0
- tools/bolt.diy/services/execution-governor/index.ts +683 -0
- tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
- tools/bolt.diy/services/execution-governor/package.json +31 -0
- tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
- tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
- tools/bolt.diy/services/execution-governor/types.ts +145 -0
- tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
- tools/bolt.diy/services/headless-executor/executor.ts +210 -0
- tools/bolt.diy/services/headless-executor/index.ts +323 -0
- tools/bolt.diy/services/headless-executor/package.json +27 -0
- tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
- tools/bolt.diy/services/headless-executor/types.ts +38 -0
- tools/bolt.diy/test-workflows.sh +240 -0
- tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
- tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
- tools/bolt.diy/tests/mandates/complex.json +53 -0
- tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
- tools/bolt.diy/tests/mandates/simple.json +35 -0
- tools/bolt.diy/tsconfig.json +37 -0
- tools/bolt.diy/types/istextorbinary.d.ts +15 -0
- tools/bolt.diy/uno.config.ts +279 -0
- tools/bolt.diy/vite-electron.config.ts +76 -0
- tools/bolt.diy/vite.config.ts +112 -0
- tools/bolt.diy/worker-configuration.d.ts +22 -0
- tools/bolt.diy/wrangler.toml +6 -0
- tools/code_generator.py +461 -0
- tools/file_operations.py +465 -0
- tools/mandate_generator.py +337 -0
- tools/mcpClientUtils.py +1216 -0
- tools/sensors.py +285 -0
- utils/Agent_types.py +15 -0
- utils/AnyToStr.py +0 -0
- utils/HHCS.py +277 -0
- utils/__init__.py +30 -0
- utils/agent.py +3627 -0
- utils/aop.py +2948 -0
- utils/canonical.py +143 -0
- utils/conversation.py +1195 -0
- utils/doctrine_versioning +230 -0
- utils/formatter.py +474 -0
- utils/ledger.py +311 -0
- utils/out_types.py +16 -0
- utils/rollback.py +339 -0
- utils/router.py +929 -0
- utils/tui.py +1908 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
|
2
|
+
import { streamText } from '~/lib/.server/llm/stream-text';
|
|
3
|
+
import type { IProviderSetting, ProviderInfo } from '~/types/model';
|
|
4
|
+
import { generateText } from 'ai';
|
|
5
|
+
import { PROVIDER_LIST } from '~/utils/constants';
|
|
6
|
+
import { MAX_TOKENS, PROVIDER_COMPLETION_LIMITS, isReasoningModel } from '~/lib/.server/llm/constants';
|
|
7
|
+
import { LLMManager } from '~/lib/modules/llm/manager';
|
|
8
|
+
import type { ModelInfo } from '~/lib/modules/llm/types';
|
|
9
|
+
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
|
|
10
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
11
|
+
|
|
12
|
+
export async function action(args: ActionFunctionArgs) {
|
|
13
|
+
return llmCallAction(args);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function getModelList(options: {
|
|
17
|
+
apiKeys?: Record<string, string>;
|
|
18
|
+
providerSettings?: Record<string, IProviderSetting>;
|
|
19
|
+
serverEnv?: Record<string, string>;
|
|
20
|
+
}) {
|
|
21
|
+
const llmManager = LLMManager.getInstance(import.meta.env);
|
|
22
|
+
return llmManager.updateModelList(options);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const logger = createScopedLogger('api.llmcall');
|
|
26
|
+
|
|
27
|
+
function getCompletionTokenLimit(modelDetails: ModelInfo): number {
|
|
28
|
+
// 1. If model specifies completion tokens, use that
|
|
29
|
+
if (modelDetails.maxCompletionTokens && modelDetails.maxCompletionTokens > 0) {
|
|
30
|
+
return modelDetails.maxCompletionTokens;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 2. Use provider-specific default
|
|
34
|
+
const providerDefault = PROVIDER_COMPLETION_LIMITS[modelDetails.provider];
|
|
35
|
+
|
|
36
|
+
if (providerDefault) {
|
|
37
|
+
return providerDefault;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 3. Final fallback to MAX_TOKENS, but cap at reasonable limit for safety
|
|
41
|
+
return Math.min(MAX_TOKENS, 16384);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function validateTokenLimits(modelDetails: ModelInfo, requestedTokens: number): { valid: boolean; error?: string } {
|
|
45
|
+
const modelMaxTokens = modelDetails.maxTokenAllowed || 128000;
|
|
46
|
+
const maxCompletionTokens = getCompletionTokenLimit(modelDetails);
|
|
47
|
+
|
|
48
|
+
// Check against model's context window
|
|
49
|
+
if (requestedTokens > modelMaxTokens) {
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
error: `Requested tokens (${requestedTokens}) exceed model's context window (${modelMaxTokens}). Please reduce your request size.`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check against completion token limits
|
|
57
|
+
if (requestedTokens > maxCompletionTokens) {
|
|
58
|
+
return {
|
|
59
|
+
valid: false,
|
|
60
|
+
error: `Requested tokens (${requestedTokens}) exceed model's completion limit (${maxCompletionTokens}). Consider using a model with higher token limits.`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return { valid: true };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function llmCallAction({ context, request }: ActionFunctionArgs) {
|
|
68
|
+
const { system, message, model, provider, streamOutput } = await request.json<{
|
|
69
|
+
system: string;
|
|
70
|
+
message: string;
|
|
71
|
+
model: string;
|
|
72
|
+
provider: ProviderInfo;
|
|
73
|
+
streamOutput?: boolean;
|
|
74
|
+
}>();
|
|
75
|
+
|
|
76
|
+
const { name: providerName } = provider;
|
|
77
|
+
|
|
78
|
+
// validate 'model' and 'provider' fields
|
|
79
|
+
if (!model || typeof model !== 'string') {
|
|
80
|
+
throw new Response('Invalid or missing model', {
|
|
81
|
+
status: 400,
|
|
82
|
+
statusText: 'Bad Request',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!providerName || typeof providerName !== 'string') {
|
|
87
|
+
throw new Response('Invalid or missing provider', {
|
|
88
|
+
status: 400,
|
|
89
|
+
statusText: 'Bad Request',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
94
|
+
const apiKeys = getApiKeysFromCookie(cookieHeader);
|
|
95
|
+
const providerSettings = getProviderSettingsFromCookie(cookieHeader);
|
|
96
|
+
|
|
97
|
+
if (streamOutput) {
|
|
98
|
+
try {
|
|
99
|
+
const result = await streamText({
|
|
100
|
+
options: {
|
|
101
|
+
system,
|
|
102
|
+
},
|
|
103
|
+
messages: [
|
|
104
|
+
{
|
|
105
|
+
role: 'user',
|
|
106
|
+
content: `${message}`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
env: context.cloudflare?.env as any,
|
|
110
|
+
apiKeys,
|
|
111
|
+
providerSettings,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return new Response(result.textStream, {
|
|
115
|
+
status: 200,
|
|
116
|
+
headers: {
|
|
117
|
+
'Content-Type': 'text/plain; charset=utf-8',
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
} catch (error: unknown) {
|
|
121
|
+
console.log(error);
|
|
122
|
+
|
|
123
|
+
if (error instanceof Error && error.message?.includes('API key')) {
|
|
124
|
+
throw new Response('Invalid or missing API key', {
|
|
125
|
+
status: 401,
|
|
126
|
+
statusText: 'Unauthorized',
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Handle token limit errors with helpful messages
|
|
131
|
+
if (
|
|
132
|
+
error instanceof Error &&
|
|
133
|
+
(error.message?.includes('max_tokens') ||
|
|
134
|
+
error.message?.includes('token') ||
|
|
135
|
+
error.message?.includes('exceeds') ||
|
|
136
|
+
error.message?.includes('maximum'))
|
|
137
|
+
) {
|
|
138
|
+
throw new Response(
|
|
139
|
+
`Token limit error: ${error.message}. Try reducing your request size or using a model with higher token limits.`,
|
|
140
|
+
{
|
|
141
|
+
status: 400,
|
|
142
|
+
statusText: 'Token Limit Exceeded',
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
throw new Response(null, {
|
|
148
|
+
status: 500,
|
|
149
|
+
statusText: 'Internal Server Error',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
try {
|
|
154
|
+
const models = await getModelList({ apiKeys, providerSettings, serverEnv: context.cloudflare?.env as any });
|
|
155
|
+
const modelDetails = models.find((m: ModelInfo) => m.name === model);
|
|
156
|
+
|
|
157
|
+
if (!modelDetails) {
|
|
158
|
+
throw new Error('Model not found');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const dynamicMaxTokens = modelDetails ? getCompletionTokenLimit(modelDetails) : Math.min(MAX_TOKENS, 16384);
|
|
162
|
+
|
|
163
|
+
// Validate token limits before making API request
|
|
164
|
+
const validation = validateTokenLimits(modelDetails, dynamicMaxTokens);
|
|
165
|
+
|
|
166
|
+
if (!validation.valid) {
|
|
167
|
+
throw new Response(validation.error, {
|
|
168
|
+
status: 400,
|
|
169
|
+
statusText: 'Token Limit Exceeded',
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const providerInfo = PROVIDER_LIST.find((p) => p.name === provider.name);
|
|
174
|
+
|
|
175
|
+
if (!providerInfo) {
|
|
176
|
+
throw new Error('Provider not found');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
logger.info(`Generating response Provider: ${provider.name}, Model: ${modelDetails.name}`);
|
|
180
|
+
|
|
181
|
+
// DEBUG: Log reasoning model detection
|
|
182
|
+
const isReasoning = isReasoningModel(modelDetails.name);
|
|
183
|
+
logger.info(`DEBUG: Model "${modelDetails.name}" detected as reasoning model: ${isReasoning}`);
|
|
184
|
+
|
|
185
|
+
// Use maxCompletionTokens for reasoning models (o1, GPT-5), maxTokens for traditional models
|
|
186
|
+
const tokenParams = isReasoning ? { maxCompletionTokens: dynamicMaxTokens } : { maxTokens: dynamicMaxTokens };
|
|
187
|
+
|
|
188
|
+
// Filter out unsupported parameters for reasoning models
|
|
189
|
+
const baseParams = {
|
|
190
|
+
system,
|
|
191
|
+
messages: [
|
|
192
|
+
{
|
|
193
|
+
role: 'user' as const,
|
|
194
|
+
content: `${message}`,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
model: providerInfo.getModelInstance({
|
|
198
|
+
model: modelDetails.name,
|
|
199
|
+
serverEnv: context.cloudflare?.env as any,
|
|
200
|
+
apiKeys,
|
|
201
|
+
providerSettings,
|
|
202
|
+
}),
|
|
203
|
+
...tokenParams,
|
|
204
|
+
toolChoice: 'none' as const,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// For reasoning models, set temperature to 1 (required by OpenAI API)
|
|
208
|
+
const finalParams = isReasoning
|
|
209
|
+
? { ...baseParams, temperature: 1 } // Set to 1 for reasoning models (only supported value)
|
|
210
|
+
: { ...baseParams, temperature: 0 };
|
|
211
|
+
|
|
212
|
+
// DEBUG: Log final parameters
|
|
213
|
+
logger.info(
|
|
214
|
+
`DEBUG: Final params for model "${modelDetails.name}":`,
|
|
215
|
+
JSON.stringify(
|
|
216
|
+
{
|
|
217
|
+
isReasoning,
|
|
218
|
+
hasTemperature: 'temperature' in finalParams,
|
|
219
|
+
hasMaxTokens: 'maxTokens' in finalParams,
|
|
220
|
+
hasMaxCompletionTokens: 'maxCompletionTokens' in finalParams,
|
|
221
|
+
paramKeys: Object.keys(finalParams).filter((key) => !['model', 'messages', 'system'].includes(key)),
|
|
222
|
+
tokenParams,
|
|
223
|
+
finalParams: Object.fromEntries(
|
|
224
|
+
Object.entries(finalParams).filter(([key]) => !['model', 'messages', 'system'].includes(key)),
|
|
225
|
+
),
|
|
226
|
+
},
|
|
227
|
+
null,
|
|
228
|
+
2,
|
|
229
|
+
),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const result = await generateText(finalParams);
|
|
233
|
+
logger.info(`Generated response`);
|
|
234
|
+
|
|
235
|
+
return new Response(JSON.stringify(result), {
|
|
236
|
+
status: 200,
|
|
237
|
+
headers: {
|
|
238
|
+
'Content-Type': 'application/json',
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
} catch (error: unknown) {
|
|
242
|
+
console.log(error);
|
|
243
|
+
|
|
244
|
+
const errorResponse = {
|
|
245
|
+
error: true,
|
|
246
|
+
message: error instanceof Error ? error.message : 'An unexpected error occurred',
|
|
247
|
+
statusCode: (error as any).statusCode || 500,
|
|
248
|
+
isRetryable: (error as any).isRetryable !== false,
|
|
249
|
+
provider: (error as any).provider || 'unknown',
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
if (error instanceof Error && error.message?.includes('API key')) {
|
|
253
|
+
return new Response(
|
|
254
|
+
JSON.stringify({
|
|
255
|
+
...errorResponse,
|
|
256
|
+
message: 'Invalid or missing API key',
|
|
257
|
+
statusCode: 401,
|
|
258
|
+
isRetryable: false,
|
|
259
|
+
}),
|
|
260
|
+
{
|
|
261
|
+
status: 401,
|
|
262
|
+
headers: { 'Content-Type': 'application/json' },
|
|
263
|
+
statusText: 'Unauthorized',
|
|
264
|
+
},
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Handle token limit errors with helpful messages
|
|
269
|
+
if (
|
|
270
|
+
error instanceof Error &&
|
|
271
|
+
(error.message?.includes('max_tokens') ||
|
|
272
|
+
error.message?.includes('token') ||
|
|
273
|
+
error.message?.includes('exceeds') ||
|
|
274
|
+
error.message?.includes('maximum'))
|
|
275
|
+
) {
|
|
276
|
+
return new Response(
|
|
277
|
+
JSON.stringify({
|
|
278
|
+
...errorResponse,
|
|
279
|
+
message: `Token limit error: ${error.message}. Try reducing your request size or using a model with higher token limits.`,
|
|
280
|
+
statusCode: 400,
|
|
281
|
+
isRetryable: false,
|
|
282
|
+
}),
|
|
283
|
+
{
|
|
284
|
+
status: 400,
|
|
285
|
+
headers: { 'Content-Type': 'application/json' },
|
|
286
|
+
statusText: 'Token Limit Exceeded',
|
|
287
|
+
},
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return new Response(JSON.stringify(errorResponse), {
|
|
292
|
+
status: errorResponse.statusCode,
|
|
293
|
+
headers: { 'Content-Type': 'application/json' },
|
|
294
|
+
statusText: 'Error',
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mandate API endpoint for autonomous code generation.
|
|
3
|
+
*
|
|
4
|
+
* Receives structured mandates from CorporateSwarm and executes
|
|
5
|
+
* code generation cycles autonomously with governance oversight.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
|
9
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
10
|
+
import type { Mandate, ExecutionResult } from '~/types/mandate';
|
|
11
|
+
import { eventRegistry } from '~/lib/runtime/execution-events';
|
|
12
|
+
import { createEventStreamResponse, broadcastEvent } from '~/lib/runtime/event-stream';
|
|
13
|
+
|
|
14
|
+
const logger = createScopedLogger('api.mandate');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Validate mandate structure and constraints.
|
|
18
|
+
*/
|
|
19
|
+
function validateMandate(mandate: Mandate): { valid: boolean; errors: string[] } {
|
|
20
|
+
const errors: string[] = [];
|
|
21
|
+
|
|
22
|
+
// Validate mandate_id
|
|
23
|
+
if (!mandate.mandate_id || typeof mandate.mandate_id !== 'string') {
|
|
24
|
+
errors.push('mandate_id is required and must be a string');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Validate objectives
|
|
28
|
+
if (!Array.isArray(mandate.objectives) || mandate.objectives.length === 0) {
|
|
29
|
+
errors.push('objectives must be a non-empty array');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Validate constraints
|
|
33
|
+
if (!mandate.constraints) {
|
|
34
|
+
errors.push('constraints are required');
|
|
35
|
+
} else {
|
|
36
|
+
if (mandate.constraints.maxDependencies < 0) {
|
|
37
|
+
errors.push('maxDependencies must be non-negative');
|
|
38
|
+
}
|
|
39
|
+
if (mandate.constraints.maxFileSize < 0) {
|
|
40
|
+
errors.push('maxFileSize must be non-negative');
|
|
41
|
+
}
|
|
42
|
+
if (mandate.constraints.maxFiles < 0) {
|
|
43
|
+
errors.push('maxFiles must be non-negative');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Validate budget
|
|
48
|
+
if (!mandate.budget) {
|
|
49
|
+
errors.push('budget is required');
|
|
50
|
+
} else {
|
|
51
|
+
if (mandate.budget.token < 0) {
|
|
52
|
+
errors.push('budget.token must be non-negative');
|
|
53
|
+
}
|
|
54
|
+
if (mandate.budget.time < 0) {
|
|
55
|
+
errors.push('budget.time must be non-negative');
|
|
56
|
+
}
|
|
57
|
+
if (mandate.budget.cost < 0) {
|
|
58
|
+
errors.push('budget.cost must be non-negative');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Validate deliverables
|
|
63
|
+
if (!Array.isArray(mandate.deliverables) || mandate.deliverables.length === 0) {
|
|
64
|
+
errors.push('deliverables must be a non-empty array');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Validate iteration_config
|
|
68
|
+
if (!mandate.iteration_config) {
|
|
69
|
+
errors.push('iteration_config is required');
|
|
70
|
+
} else {
|
|
71
|
+
if (mandate.iteration_config.max_iterations < 1) {
|
|
72
|
+
errors.push('max_iterations must be at least 1');
|
|
73
|
+
}
|
|
74
|
+
if (
|
|
75
|
+
mandate.iteration_config.quality_threshold < 0 ||
|
|
76
|
+
mandate.iteration_config.quality_threshold > 1
|
|
77
|
+
) {
|
|
78
|
+
errors.push('quality_threshold must be between 0 and 1');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Validate deployment config if enabled
|
|
83
|
+
if (mandate.deployment?.enabled) {
|
|
84
|
+
if (!mandate.deployment.provider) {
|
|
85
|
+
errors.push('deployment.provider is required when deployment is enabled');
|
|
86
|
+
} else {
|
|
87
|
+
const validProviders = ['netlify', 'vercel', 'github', 'gitlab'];
|
|
88
|
+
if (!validProviders.includes(mandate.deployment.provider)) {
|
|
89
|
+
errors.push(`deployment.provider must be one of: ${validProviders.join(', ')}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
valid: errors.length === 0,
|
|
96
|
+
errors,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Main mandate action handler.
|
|
102
|
+
*/
|
|
103
|
+
export async function action(args: ActionFunctionArgs) {
|
|
104
|
+
return mandateAction(args);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function mandateAction({ context, request }: ActionFunctionArgs) {
|
|
108
|
+
try {
|
|
109
|
+
// Parse mandate from request
|
|
110
|
+
const mandate: Mandate = await request.json();
|
|
111
|
+
|
|
112
|
+
logger.info(`Received mandate: ${mandate.mandate_id}`);
|
|
113
|
+
|
|
114
|
+
// Validate mandate
|
|
115
|
+
const validation = validateMandate(mandate);
|
|
116
|
+
if (!validation.valid) {
|
|
117
|
+
logger.error(`Mandate validation failed: ${validation.errors.join(', ')}`);
|
|
118
|
+
return new Response(
|
|
119
|
+
JSON.stringify({
|
|
120
|
+
success: false,
|
|
121
|
+
error: 'Invalid mandate',
|
|
122
|
+
errors: validation.errors,
|
|
123
|
+
}),
|
|
124
|
+
{
|
|
125
|
+
status: 400,
|
|
126
|
+
headers: { 'Content-Type': 'application/json' },
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Check if this is a request for event stream
|
|
132
|
+
const url = new URL(request.url);
|
|
133
|
+
const streamRequested = url.searchParams.get('stream') === 'true';
|
|
134
|
+
|
|
135
|
+
if (streamRequested) {
|
|
136
|
+
// Return event stream for real-time observability
|
|
137
|
+
return createEventStreamResponse(mandate.mandate_id);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check if Execution Governor is enabled
|
|
141
|
+
const governorEnabled = process.env.EXECUTION_GOVERNOR_ENABLED === 'true' ||
|
|
142
|
+
process.env.EXECUTION_GOVERNOR_URL !== undefined;
|
|
143
|
+
const governorUrl = process.env.EXECUTION_GOVERNOR_URL || 'http://localhost:3000';
|
|
144
|
+
|
|
145
|
+
if (governorEnabled) {
|
|
146
|
+
// Forward mandate to Execution Governor
|
|
147
|
+
try {
|
|
148
|
+
logger.info(`Forwarding mandate ${mandate.mandate_id} to Execution Governor at ${governorUrl}`);
|
|
149
|
+
|
|
150
|
+
const governorResponse = await fetch(`${governorUrl}/mandates`, {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: {
|
|
153
|
+
'Content-Type': 'application/json',
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify(mandate),
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if (!governorResponse.ok) {
|
|
159
|
+
const errorText = await governorResponse.text();
|
|
160
|
+
logger.error(`Governor rejected mandate: ${governorResponse.status} - ${errorText}`);
|
|
161
|
+
|
|
162
|
+
// Fall back to direct execution if governor fails
|
|
163
|
+
logger.warn('Falling back to direct execution mode');
|
|
164
|
+
} else {
|
|
165
|
+
const governorData = await governorResponse.json() as { queue_position?: number; estimated_wait_time?: number };
|
|
166
|
+
logger.info(`Mandate ${mandate.mandate_id} queued in governor:`, governorData);
|
|
167
|
+
|
|
168
|
+
// Initialize event emitter for observability
|
|
169
|
+
const emitter = eventRegistry.getEmitter(mandate.mandate_id);
|
|
170
|
+
|
|
171
|
+
// Store mandate for later retrieval
|
|
172
|
+
eventRegistry.storeMandate(mandate.mandate_id, mandate);
|
|
173
|
+
|
|
174
|
+
emitter.emitLog('info', `Mandate ${mandate.mandate_id} queued in Execution Governor`, 'api');
|
|
175
|
+
|
|
176
|
+
return new Response(
|
|
177
|
+
JSON.stringify({
|
|
178
|
+
success: true,
|
|
179
|
+
mandate_id: mandate.mandate_id,
|
|
180
|
+
status: 'queued',
|
|
181
|
+
message: 'Mandate queued in Execution Governor',
|
|
182
|
+
queue_position: governorData.queue_position,
|
|
183
|
+
estimated_wait_time: governorData.estimated_wait_time,
|
|
184
|
+
event_stream_url: `/api/mandate?stream=true&mandate_id=${mandate.mandate_id}`,
|
|
185
|
+
governor_url: governorUrl,
|
|
186
|
+
}),
|
|
187
|
+
{
|
|
188
|
+
status: 202, // Accepted
|
|
189
|
+
headers: { 'Content-Type': 'application/json' },
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
} catch (error) {
|
|
194
|
+
logger.error('Error forwarding to governor, falling back to direct execution:', error);
|
|
195
|
+
// Fall through to direct execution
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Direct execution mode (fallback or when governor disabled)
|
|
200
|
+
// Initialize event emitter for this mandate
|
|
201
|
+
const emitter = eventRegistry.getEmitter(mandate.mandate_id);
|
|
202
|
+
|
|
203
|
+
// Store mandate for later retrieval
|
|
204
|
+
eventRegistry.storeMandate(mandate.mandate_id, mandate);
|
|
205
|
+
|
|
206
|
+
// Emit initial acceptance event
|
|
207
|
+
emitter.emitIterationStart(0, {
|
|
208
|
+
model_used: 'pending',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
emitter.emitLog('info', `Mandate ${mandate.mandate_id} accepted and queued for execution`, 'api');
|
|
212
|
+
|
|
213
|
+
// Note: Actual execution will be handled client-side where WebContainer is available
|
|
214
|
+
// The mandate is validated and accepted here, execution happens via client-side MandateExecutor
|
|
215
|
+
logger.info(`Mandate ${mandate.mandate_id} accepted, ready for client-side execution`);
|
|
216
|
+
|
|
217
|
+
return new Response(
|
|
218
|
+
JSON.stringify({
|
|
219
|
+
success: true,
|
|
220
|
+
mandate_id: mandate.mandate_id,
|
|
221
|
+
status: 'accepted',
|
|
222
|
+
message: 'Mandate accepted, execution started',
|
|
223
|
+
event_stream_url: `/api/mandate?stream=true&mandate_id=${mandate.mandate_id}`,
|
|
224
|
+
}),
|
|
225
|
+
{
|
|
226
|
+
status: 202, // Accepted
|
|
227
|
+
headers: { 'Content-Type': 'application/json' },
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
} catch (error: unknown) {
|
|
231
|
+
logger.error('Error processing mandate:', error);
|
|
232
|
+
|
|
233
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
234
|
+
|
|
235
|
+
return new Response(
|
|
236
|
+
JSON.stringify({
|
|
237
|
+
success: false,
|
|
238
|
+
error: 'Failed to process mandate',
|
|
239
|
+
message: errorMessage,
|
|
240
|
+
}),
|
|
241
|
+
{
|
|
242
|
+
status: 500,
|
|
243
|
+
headers: { 'Content-Type': 'application/json' },
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* GET handler for mandate status and event polling.
|
|
251
|
+
*/
|
|
252
|
+
export async function loader({ request }: ActionFunctionArgs) {
|
|
253
|
+
const url = new URL(request.url);
|
|
254
|
+
|
|
255
|
+
// Check if this is a request for active mandates list (no mandate_id required)
|
|
256
|
+
if (url.searchParams.get('list') === 'true') {
|
|
257
|
+
const allMandateIds = eventRegistry.getActiveMandates();
|
|
258
|
+
const mandates = allMandateIds.slice(-10).reverse().map(mandateId => {
|
|
259
|
+
const emitter = eventRegistry.getEmitter(mandateId);
|
|
260
|
+
const events = emitter.getEvents();
|
|
261
|
+
const latestEvent = events[events.length - 1];
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
mandate_id: mandateId,
|
|
265
|
+
last_event_time: latestEvent?.timestamp || Date.now() / 1000,
|
|
266
|
+
event_count: events.length,
|
|
267
|
+
status: latestEvent?.type === 'iteration_end' ? 'completed' :
|
|
268
|
+
latestEvent?.type === 'error' ? 'failed' :
|
|
269
|
+
events.length > 0 ? 'running' : 'accepted'
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return new Response(
|
|
274
|
+
JSON.stringify({
|
|
275
|
+
mandates,
|
|
276
|
+
count: mandates.length,
|
|
277
|
+
}),
|
|
278
|
+
{
|
|
279
|
+
status: 200,
|
|
280
|
+
headers: { 'Content-Type': 'application/json' },
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// For other requests, mandate_id is required
|
|
286
|
+
const mandateId = url.searchParams.get('mandate_id');
|
|
287
|
+
|
|
288
|
+
if (!mandateId) {
|
|
289
|
+
return new Response(
|
|
290
|
+
JSON.stringify({
|
|
291
|
+
error: 'mandate_id parameter is required (or use ?list=true for mandates list)',
|
|
292
|
+
}),
|
|
293
|
+
{
|
|
294
|
+
status: 400,
|
|
295
|
+
headers: { 'Content-Type': 'application/json' },
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Check if this is a request for the mandate object itself
|
|
301
|
+
if (url.searchParams.get('get') === 'true') {
|
|
302
|
+
const storedMandate = eventRegistry.getMandate(mandateId);
|
|
303
|
+
if (storedMandate) {
|
|
304
|
+
return new Response(
|
|
305
|
+
JSON.stringify({
|
|
306
|
+
mandate: storedMandate,
|
|
307
|
+
}),
|
|
308
|
+
{
|
|
309
|
+
status: 200,
|
|
310
|
+
headers: { 'Content-Type': 'application/json' },
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
} else {
|
|
314
|
+
return new Response(
|
|
315
|
+
JSON.stringify({
|
|
316
|
+
error: 'Mandate not found',
|
|
317
|
+
}),
|
|
318
|
+
{
|
|
319
|
+
status: 404,
|
|
320
|
+
headers: { 'Content-Type': 'application/json' },
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Check if streaming is requested
|
|
327
|
+
const streamRequested = url.searchParams.get('stream') === 'true';
|
|
328
|
+
if (streamRequested) {
|
|
329
|
+
return createEventStreamResponse(mandateId);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Return current events for polling
|
|
333
|
+
const { getMandateEvents, getMandateEventsSince } = await import('~/lib/runtime/event-stream');
|
|
334
|
+
const since = url.searchParams.get('since');
|
|
335
|
+
const events = since
|
|
336
|
+
? getMandateEventsSince(mandateId, parseInt(since, 10))
|
|
337
|
+
: getMandateEvents(mandateId);
|
|
338
|
+
|
|
339
|
+
return new Response(
|
|
340
|
+
JSON.stringify({
|
|
341
|
+
mandate_id: mandateId,
|
|
342
|
+
events,
|
|
343
|
+
count: events.length,
|
|
344
|
+
}),
|
|
345
|
+
{
|
|
346
|
+
status: 200,
|
|
347
|
+
headers: { 'Content-Type': 'application/json' },
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
2
|
+
import { MCPService } from '~/lib/services/mcpService';
|
|
3
|
+
|
|
4
|
+
const logger = createScopedLogger('api.mcp-check');
|
|
5
|
+
|
|
6
|
+
export async function loader() {
|
|
7
|
+
try {
|
|
8
|
+
const mcpService = MCPService.getInstance();
|
|
9
|
+
const serverTools = await mcpService.checkServersAvailabilities();
|
|
10
|
+
|
|
11
|
+
return Response.json(serverTools);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
logger.error('Error checking MCP servers:', error);
|
|
14
|
+
return Response.json({ error: 'Failed to check MCP servers' }, { status: 500 });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
|
2
|
+
import { createScopedLogger } from '~/utils/logger';
|
|
3
|
+
import { MCPService, type MCPConfig } from '~/lib/services/mcpService';
|
|
4
|
+
|
|
5
|
+
const logger = createScopedLogger('api.mcp-update-config');
|
|
6
|
+
|
|
7
|
+
export async function action({ request }: ActionFunctionArgs) {
|
|
8
|
+
try {
|
|
9
|
+
const mcpConfig = (await request.json()) as MCPConfig;
|
|
10
|
+
|
|
11
|
+
if (!mcpConfig || typeof mcpConfig !== 'object') {
|
|
12
|
+
return Response.json({ error: 'Invalid MCP servers configuration' }, { status: 400 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const mcpService = MCPService.getInstance();
|
|
16
|
+
const serverTools = await mcpService.updateConfig(mcpConfig);
|
|
17
|
+
|
|
18
|
+
return Response.json(serverTools);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
logger.error('Error updating MCP config:', error);
|
|
21
|
+
return Response.json({ error: 'Failed to update MCP config' }, { status: 500 });
|
|
22
|
+
}
|
|
23
|
+
}
|