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