ruflo 3.5.2 → 3.5.3
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.
- package/dist/rvf.manifest.json +295 -0
- package/package.json +16 -2
- package/src/chat-ui/Dockerfile +25 -0
- package/src/chat-ui/patch-mcp-url-safety.sh +28 -0
- package/src/chat-ui/static/chatui/icon-144x144.png +0 -0
- package/src/chat-ui/static/chatui/omni-welcome.gif +0 -0
- package/src/config/config.example.json +76 -0
- package/src/mcp-bridge/Dockerfile +45 -0
- package/src/mcp-bridge/index.js +1668 -0
- package/src/mcp-bridge/mcp-stdio-kernel.js +159 -0
- package/src/mcp-bridge/package.json +17 -0
- package/src/mcp-bridge/test-harness.js +470 -0
- package/src/nginx/Dockerfile +10 -0
- package/src/nginx/nginx.conf +67 -0
- package/src/nginx/static/favicon-dark.svg +4 -0
- package/src/nginx/static/favicon.svg +4 -0
- package/src/nginx/static/icon.svg +5 -0
- package/src/nginx/static/logo.svg +9 -0
- package/src/nginx/static/manifest.json +22 -0
- package/src/nginx/static/welcome.js +184 -0
- package/src/ruvocal/.claude/skills/add-model-descriptions/SKILL.md +73 -0
- package/src/ruvocal/.devcontainer/Dockerfile +9 -0
- package/src/ruvocal/.devcontainer/devcontainer.json +36 -0
- package/src/ruvocal/.dockerignore +13 -0
- package/src/ruvocal/.env +194 -0
- package/src/ruvocal/.env.ci +1 -0
- package/src/ruvocal/.eslintignore +13 -0
- package/src/ruvocal/.eslintrc.cjs +45 -0
- package/src/ruvocal/.github/ISSUE_TEMPLATE/bug-report--chat-ui-.md +43 -0
- package/src/ruvocal/.github/ISSUE_TEMPLATE/config-support.md +9 -0
- package/src/ruvocal/.github/ISSUE_TEMPLATE/feature-request--chat-ui-.md +17 -0
- package/src/ruvocal/.github/ISSUE_TEMPLATE/huggingchat.md +11 -0
- package/src/ruvocal/.github/release.yml +16 -0
- package/src/ruvocal/.github/workflows/build-docs.yml +18 -0
- package/src/ruvocal/.github/workflows/build-image.yml +142 -0
- package/src/ruvocal/.github/workflows/build-pr-docs.yml +20 -0
- package/src/ruvocal/.github/workflows/deploy-dev.yml +63 -0
- package/src/ruvocal/.github/workflows/deploy-prod.yml +78 -0
- package/src/ruvocal/.github/workflows/lint-and-test.yml +84 -0
- package/src/ruvocal/.github/workflows/slugify.yaml +72 -0
- package/src/ruvocal/.github/workflows/trufflehog.yml +17 -0
- package/src/ruvocal/.github/workflows/upload-pr-documentation.yml +16 -0
- package/src/ruvocal/.husky/lint-stage-config.js +4 -0
- package/src/ruvocal/.husky/pre-commit +2 -0
- package/src/ruvocal/.prettierignore +14 -0
- package/src/ruvocal/.prettierrc +7 -0
- package/src/ruvocal/.vscode/launch.json +11 -0
- package/src/ruvocal/.vscode/settings.json +14 -0
- package/src/ruvocal/CLAUDE.md +126 -0
- package/src/ruvocal/Dockerfile +93 -0
- package/src/ruvocal/LICENSE +203 -0
- package/src/ruvocal/PRIVACY.md +41 -0
- package/src/ruvocal/README.md +190 -0
- package/src/ruvocal/chart/Chart.yaml +5 -0
- package/src/ruvocal/chart/env/dev.yaml +260 -0
- package/src/ruvocal/chart/env/prod.yaml +273 -0
- package/src/ruvocal/chart/templates/_helpers.tpl +22 -0
- package/src/ruvocal/chart/templates/config.yaml +10 -0
- package/src/ruvocal/chart/templates/deployment.yaml +81 -0
- package/src/ruvocal/chart/templates/hpa.yaml +45 -0
- package/src/ruvocal/chart/templates/infisical.yaml +24 -0
- package/src/ruvocal/chart/templates/ingress-internal.yaml +32 -0
- package/src/ruvocal/chart/templates/ingress.yaml +32 -0
- package/src/ruvocal/chart/templates/network-policy.yaml +36 -0
- package/src/ruvocal/chart/templates/service-account.yaml +13 -0
- package/src/ruvocal/chart/templates/service-monitor.yaml +17 -0
- package/src/ruvocal/chart/templates/service.yaml +21 -0
- package/src/ruvocal/chart/values.yaml +73 -0
- package/src/ruvocal/docker-compose.yml +21 -0
- package/src/ruvocal/docs/adr/ADR-029-HUGGINGFACE-CHAT-UI-CLOUD-RUN.md +1236 -0
- package/src/ruvocal/docs/adr/ADR-033-RUVECTOR-RUFLO-MCP-INTEGRATION.md +111 -0
- package/src/ruvocal/docs/adr/ADR-034-OPTIONAL-MCP-BACKENDS.md +117 -0
- package/src/ruvocal/docs/adr/ADR-035-MCP-TOOL-GROUPS.md +186 -0
- package/src/ruvocal/docs/adr/ADR-037-AUTOPILOT-CHAT-MODE.md +1500 -0
- package/src/ruvocal/docs/adr/ADR-038-RUVOCAL-FORK.md +286 -0
- package/src/ruvocal/docs/source/_toctree.yml +30 -0
- package/src/ruvocal/docs/source/configuration/common-issues.md +38 -0
- package/src/ruvocal/docs/source/configuration/llm-router.md +105 -0
- package/src/ruvocal/docs/source/configuration/mcp-tools.md +84 -0
- package/src/ruvocal/docs/source/configuration/metrics.md +9 -0
- package/src/ruvocal/docs/source/configuration/open-id.md +57 -0
- package/src/ruvocal/docs/source/configuration/overview.md +89 -0
- package/src/ruvocal/docs/source/configuration/theming.md +20 -0
- package/src/ruvocal/docs/source/developing/architecture.md +48 -0
- package/src/ruvocal/docs/source/index.md +53 -0
- package/src/ruvocal/docs/source/installation/docker.md +43 -0
- package/src/ruvocal/docs/source/installation/helm.md +43 -0
- package/src/ruvocal/docs/source/installation/local.md +62 -0
- package/src/ruvocal/entrypoint.sh +19 -0
- package/src/ruvocal/mcp-bridge/.claude-flow/agents/store.json +27 -0
- package/src/ruvocal/mcp-bridge/.claude-flow/daemon-state.json +130 -0
- package/src/ruvocal/mcp-bridge/.claude-flow/daemon.log +0 -0
- package/src/ruvocal/mcp-bridge/.claude-flow/daemon.pid +1 -0
- package/src/ruvocal/mcp-bridge/.claude-flow/tasks/store.json +21 -0
- package/src/ruvocal/mcp-bridge/.swarm/hnsw.index +0 -0
- package/src/ruvocal/mcp-bridge/.swarm/hnsw.metadata.json +1 -0
- package/src/ruvocal/mcp-bridge/.swarm/memory.db +0 -0
- package/src/ruvocal/mcp-bridge/.swarm/model-router-state.json +14 -0
- package/src/ruvocal/mcp-bridge/.swarm/schema.sql +305 -0
- package/src/ruvocal/mcp-bridge/Dockerfile +45 -0
- package/src/ruvocal/mcp-bridge/cloudbuild.yaml +49 -0
- package/src/ruvocal/mcp-bridge/index.js +1864 -0
- package/src/ruvocal/mcp-bridge/mcp-stdio-kernel.js +159 -0
- package/src/ruvocal/mcp-bridge/package-lock.json +762 -0
- package/src/ruvocal/mcp-bridge/package.json +17 -0
- package/src/ruvocal/mcp-bridge/test-harness.js +470 -0
- package/src/ruvocal/models/add-your-models-here.txt +1 -0
- package/src/ruvocal/package-lock.json +11741 -0
- package/src/ruvocal/package.json +121 -0
- package/src/ruvocal/postcss.config.js +6 -0
- package/src/ruvocal/rvf.manifest.json +204 -0
- package/src/ruvocal/scripts/config.ts +64 -0
- package/src/ruvocal/scripts/generate-welcome.mjs +181 -0
- package/src/ruvocal/scripts/populate.ts +288 -0
- package/src/ruvocal/scripts/samples.txt +194 -0
- package/src/ruvocal/scripts/setups/vitest-setup-client.ts +0 -0
- package/src/ruvocal/scripts/setups/vitest-setup-server.ts +44 -0
- package/src/ruvocal/scripts/updateLocalEnv.ts +48 -0
- package/src/ruvocal/src/ambient.d.ts +7 -0
- package/src/ruvocal/src/app.d.ts +29 -0
- package/src/ruvocal/src/app.html +53 -0
- package/src/ruvocal/src/hooks.server.ts +32 -0
- package/src/ruvocal/src/hooks.ts +6 -0
- package/src/ruvocal/src/lib/APIClient.ts +148 -0
- package/src/ruvocal/src/lib/actions/clickOutside.ts +18 -0
- package/src/ruvocal/src/lib/actions/snapScrollToBottom.ts +346 -0
- package/src/ruvocal/src/lib/buildPrompt.ts +33 -0
- package/src/ruvocal/src/lib/components/AnnouncementBanner.svelte +20 -0
- package/src/ruvocal/src/lib/components/BackgroundGenerationPoller.svelte +168 -0
- package/src/ruvocal/src/lib/components/CodeBlock.svelte +73 -0
- package/src/ruvocal/src/lib/components/CopyToClipBoardBtn.svelte +92 -0
- package/src/ruvocal/src/lib/components/DeleteConversationModal.svelte +75 -0
- package/src/ruvocal/src/lib/components/EditConversationModal.svelte +100 -0
- package/src/ruvocal/src/lib/components/ExpandNavigation.svelte +22 -0
- package/src/ruvocal/src/lib/components/HoverTooltip.svelte +44 -0
- package/src/ruvocal/src/lib/components/HtmlPreviewModal.svelte +143 -0
- package/src/ruvocal/src/lib/components/InfiniteScroll.svelte +50 -0
- package/src/ruvocal/src/lib/components/MobileNav.svelte +300 -0
- package/src/ruvocal/src/lib/components/Modal.svelte +115 -0
- package/src/ruvocal/src/lib/components/ModelCardMetadata.svelte +71 -0
- package/src/ruvocal/src/lib/components/NavConversationItem.svelte +151 -0
- package/src/ruvocal/src/lib/components/NavMenu.svelte +295 -0
- package/src/ruvocal/src/lib/components/Pagination.svelte +97 -0
- package/src/ruvocal/src/lib/components/PaginationArrow.svelte +27 -0
- package/src/ruvocal/src/lib/components/Portal.svelte +24 -0
- package/src/ruvocal/src/lib/components/RetryBtn.svelte +18 -0
- package/src/ruvocal/src/lib/components/RuFloUniverse.svelte +185 -0
- package/src/ruvocal/src/lib/components/ScrollToBottomBtn.svelte +47 -0
- package/src/ruvocal/src/lib/components/ScrollToPreviousBtn.svelte +77 -0
- package/src/ruvocal/src/lib/components/ShareConversationModal.svelte +182 -0
- package/src/ruvocal/src/lib/components/StopGeneratingBtn.svelte +69 -0
- package/src/ruvocal/src/lib/components/SubscribeModal.svelte +87 -0
- package/src/ruvocal/src/lib/components/Switch.svelte +36 -0
- package/src/ruvocal/src/lib/components/SystemPromptModal.svelte +44 -0
- package/src/ruvocal/src/lib/components/Toast.svelte +27 -0
- package/src/ruvocal/src/lib/components/Tooltip.svelte +30 -0
- package/src/ruvocal/src/lib/components/WelcomeModal.svelte +46 -0
- package/src/ruvocal/src/lib/components/chat/Alternatives.svelte +77 -0
- package/src/ruvocal/src/lib/components/chat/BlockWrapper.svelte +72 -0
- package/src/ruvocal/src/lib/components/chat/ChatInput.svelte +490 -0
- package/src/ruvocal/src/lib/components/chat/ChatIntroduction.svelte +123 -0
- package/src/ruvocal/src/lib/components/chat/ChatMessage.svelte +548 -0
- package/src/ruvocal/src/lib/components/chat/ChatWindow.svelte +939 -0
- package/src/ruvocal/src/lib/components/chat/FileDropzone.svelte +92 -0
- package/src/ruvocal/src/lib/components/chat/ImageLightbox.svelte +66 -0
- package/src/ruvocal/src/lib/components/chat/MarkdownBlock.svelte +23 -0
- package/src/ruvocal/src/lib/components/chat/MarkdownRenderer.svelte +69 -0
- package/src/ruvocal/src/lib/components/chat/MarkdownRenderer.svelte.test.ts +58 -0
- package/src/ruvocal/src/lib/components/chat/MessageAvatar.svelte +103 -0
- package/src/ruvocal/src/lib/components/chat/ModelSwitch.svelte +64 -0
- package/src/ruvocal/src/lib/components/chat/OpenReasoningResults.svelte +81 -0
- package/src/ruvocal/src/lib/components/chat/TaskGroup.svelte +88 -0
- package/src/ruvocal/src/lib/components/chat/ToolUpdate.svelte +273 -0
- package/src/ruvocal/src/lib/components/chat/UploadedFile.svelte +253 -0
- package/src/ruvocal/src/lib/components/chat/UrlFetchModal.svelte +203 -0
- package/src/ruvocal/src/lib/components/chat/VoiceRecorder.svelte +214 -0
- package/src/ruvocal/src/lib/components/icons/IconBurger.svelte +20 -0
- package/src/ruvocal/src/lib/components/icons/IconCheap.svelte +20 -0
- package/src/ruvocal/src/lib/components/icons/IconChevron.svelte +24 -0
- package/src/ruvocal/src/lib/components/icons/IconDazzled.svelte +40 -0
- package/src/ruvocal/src/lib/components/icons/IconFast.svelte +20 -0
- package/src/ruvocal/src/lib/components/icons/IconLoading.svelte +22 -0
- package/src/ruvocal/src/lib/components/icons/IconMCP.svelte +28 -0
- package/src/ruvocal/src/lib/components/icons/IconMoon.svelte +21 -0
- package/src/ruvocal/src/lib/components/icons/IconNew.svelte +20 -0
- package/src/ruvocal/src/lib/components/icons/IconOmni.svelte +90 -0
- package/src/ruvocal/src/lib/components/icons/IconPaperclip.svelte +24 -0
- package/src/ruvocal/src/lib/components/icons/IconPro.svelte +37 -0
- package/src/ruvocal/src/lib/components/icons/IconShare.svelte +21 -0
- package/src/ruvocal/src/lib/components/icons/IconSun.svelte +93 -0
- package/src/ruvocal/src/lib/components/icons/Logo.svelte +68 -0
- package/src/ruvocal/src/lib/components/icons/LogoHuggingFaceBorderless.svelte +54 -0
- package/src/ruvocal/src/lib/components/mcp/AddServerForm.svelte +250 -0
- package/src/ruvocal/src/lib/components/mcp/MCPServerManager.svelte +185 -0
- package/src/ruvocal/src/lib/components/mcp/ServerCard.svelte +203 -0
- package/src/ruvocal/src/lib/components/players/AudioPlayer.svelte +82 -0
- package/src/ruvocal/src/lib/components/voice/AudioWaveform.svelte +96 -0
- package/src/ruvocal/src/lib/constants/mcpExamples.ts +135 -0
- package/src/ruvocal/src/lib/constants/mime.ts +11 -0
- package/src/ruvocal/src/lib/constants/pagination.ts +1 -0
- package/src/ruvocal/src/lib/constants/publicSepToken.ts +1 -0
- package/src/ruvocal/src/lib/constants/routerExamples.ts +209 -0
- package/src/ruvocal/src/lib/createShareLink.ts +27 -0
- package/src/ruvocal/src/lib/jobs/refresh-conversation-stats.ts +297 -0
- package/src/ruvocal/src/lib/migrations/lock.ts +56 -0
- package/src/ruvocal/src/lib/migrations/migrations.spec.ts +74 -0
- package/src/ruvocal/src/lib/migrations/migrations.ts +109 -0
- package/src/ruvocal/src/lib/migrations/routines/01-update-search-assistants.ts +50 -0
- package/src/ruvocal/src/lib/migrations/routines/02-update-assistants-models.ts +48 -0
- package/src/ruvocal/src/lib/migrations/routines/04-update-message-updates.ts +151 -0
- package/src/ruvocal/src/lib/migrations/routines/05-update-message-files.ts +56 -0
- package/src/ruvocal/src/lib/migrations/routines/06-trim-message-updates.ts +56 -0
- package/src/ruvocal/src/lib/migrations/routines/08-update-featured-to-review.ts +32 -0
- package/src/ruvocal/src/lib/migrations/routines/09-delete-empty-conversations.spec.ts +214 -0
- package/src/ruvocal/src/lib/migrations/routines/09-delete-empty-conversations.ts +88 -0
- package/src/ruvocal/src/lib/migrations/routines/10-update-reports-assistantid.ts +29 -0
- package/src/ruvocal/src/lib/migrations/routines/index.ts +15 -0
- package/src/ruvocal/src/lib/server/__tests__/conversation-stop-generating.spec.ts +103 -0
- package/src/ruvocal/src/lib/server/abortRegistry.ts +57 -0
- package/src/ruvocal/src/lib/server/abortedGenerations.ts +43 -0
- package/src/ruvocal/src/lib/server/adminToken.ts +62 -0
- package/src/ruvocal/src/lib/server/api/__tests__/conversations-id.spec.ts +296 -0
- package/src/ruvocal/src/lib/server/api/__tests__/conversations-message.spec.ts +216 -0
- package/src/ruvocal/src/lib/server/api/__tests__/conversations.spec.ts +235 -0
- package/src/ruvocal/src/lib/server/api/__tests__/misc.spec.ts +72 -0
- package/src/ruvocal/src/lib/server/api/__tests__/testHelpers.ts +86 -0
- package/src/ruvocal/src/lib/server/api/__tests__/user-reports.spec.ts +78 -0
- package/src/ruvocal/src/lib/server/api/__tests__/user.spec.ts +239 -0
- package/src/ruvocal/src/lib/server/api/types.ts +37 -0
- package/src/ruvocal/src/lib/server/api/utils/requireAuth.ts +22 -0
- package/src/ruvocal/src/lib/server/api/utils/resolveConversation.ts +69 -0
- package/src/ruvocal/src/lib/server/api/utils/resolveModel.ts +27 -0
- package/src/ruvocal/src/lib/server/api/utils/superjsonResponse.ts +15 -0
- package/src/ruvocal/src/lib/server/apiToken.ts +11 -0
- package/src/ruvocal/src/lib/server/auth.ts +554 -0
- package/src/ruvocal/src/lib/server/config.ts +187 -0
- package/src/ruvocal/src/lib/server/conversation.ts +83 -0
- package/src/ruvocal/src/lib/server/database/__tests__/rvf.spec.ts +709 -0
- package/src/ruvocal/src/lib/server/database/postgres.ts +700 -0
- package/src/ruvocal/src/lib/server/database/rvf.ts +1078 -0
- package/src/ruvocal/src/lib/server/database.ts +145 -0
- package/src/ruvocal/src/lib/server/endpoints/document.ts +68 -0
- package/src/ruvocal/src/lib/server/endpoints/endpoints.ts +43 -0
- package/src/ruvocal/src/lib/server/endpoints/images.ts +211 -0
- package/src/ruvocal/src/lib/server/endpoints/openai/endpointOai.ts +266 -0
- package/src/ruvocal/src/lib/server/endpoints/openai/openAIChatToTextGenerationStream.ts +212 -0
- package/src/ruvocal/src/lib/server/endpoints/openai/openAICompletionToTextGenerationStream.ts +32 -0
- package/src/ruvocal/src/lib/server/endpoints/preprocessMessages.ts +61 -0
- package/src/ruvocal/src/lib/server/exitHandler.ts +59 -0
- package/src/ruvocal/src/lib/server/files/downloadFile.ts +34 -0
- package/src/ruvocal/src/lib/server/files/uploadFile.ts +29 -0
- package/src/ruvocal/src/lib/server/findRepoRoot.ts +13 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Black.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Bold.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-ExtraBold.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-ExtraLight.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Light.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Medium.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Regular.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-SemiBold.ttf +0 -0
- package/src/ruvocal/src/lib/server/fonts/Inter-Thin.ttf +0 -0
- package/src/ruvocal/src/lib/server/generateFromDefaultEndpoint.ts +46 -0
- package/src/ruvocal/src/lib/server/hooks/error.ts +37 -0
- package/src/ruvocal/src/lib/server/hooks/fetch.ts +22 -0
- package/src/ruvocal/src/lib/server/hooks/handle.ts +250 -0
- package/src/ruvocal/src/lib/server/hooks/init.ts +51 -0
- package/src/ruvocal/src/lib/server/isURLLocal.spec.ts +31 -0
- package/src/ruvocal/src/lib/server/isURLLocal.ts +74 -0
- package/src/ruvocal/src/lib/server/logger.ts +42 -0
- package/src/ruvocal/src/lib/server/mcp/clientPool.ts +70 -0
- package/src/ruvocal/src/lib/server/mcp/hf.ts +32 -0
- package/src/ruvocal/src/lib/server/mcp/httpClient.ts +122 -0
- package/src/ruvocal/src/lib/server/mcp/registry.ts +76 -0
- package/src/ruvocal/src/lib/server/mcp/tools.ts +196 -0
- package/src/ruvocal/src/lib/server/metrics.ts +255 -0
- package/src/ruvocal/src/lib/server/models.ts +518 -0
- package/src/ruvocal/src/lib/server/requestContext.ts +55 -0
- package/src/ruvocal/src/lib/server/router/arch.ts +230 -0
- package/src/ruvocal/src/lib/server/router/endpoint.ts +316 -0
- package/src/ruvocal/src/lib/server/router/multimodal.ts +28 -0
- package/src/ruvocal/src/lib/server/router/policy.ts +49 -0
- package/src/ruvocal/src/lib/server/router/toolsRoute.ts +51 -0
- package/src/ruvocal/src/lib/server/router/types.ts +21 -0
- package/src/ruvocal/src/lib/server/sendSlack.ts +23 -0
- package/src/ruvocal/src/lib/server/textGeneration/generate.ts +258 -0
- package/src/ruvocal/src/lib/server/textGeneration/index.ts +95 -0
- package/src/ruvocal/src/lib/server/textGeneration/mcp/fileRefs.ts +155 -0
- package/src/ruvocal/src/lib/server/textGeneration/mcp/routerResolution.ts +108 -0
- package/src/ruvocal/src/lib/server/textGeneration/mcp/runMcpFlow.ts +822 -0
- package/src/ruvocal/src/lib/server/textGeneration/mcp/toolInvocation.ts +349 -0
- package/src/ruvocal/src/lib/server/textGeneration/reasoning.ts +23 -0
- package/src/ruvocal/src/lib/server/textGeneration/title.ts +83 -0
- package/src/ruvocal/src/lib/server/textGeneration/types.ts +26 -0
- package/src/ruvocal/src/lib/server/textGeneration/utils/prepareFiles.ts +88 -0
- package/src/ruvocal/src/lib/server/textGeneration/utils/routing.ts +21 -0
- package/src/ruvocal/src/lib/server/textGeneration/utils/toolPrompt.ts +49 -0
- package/src/ruvocal/src/lib/server/urlSafety.ts +72 -0
- package/src/ruvocal/src/lib/server/usageLimits.ts +30 -0
- package/src/ruvocal/src/lib/stores/autopilotStore.svelte.ts +175 -0
- package/src/ruvocal/src/lib/stores/backgroundGenerations.svelte.ts +32 -0
- package/src/ruvocal/src/lib/stores/backgroundGenerations.ts +1 -0
- package/src/ruvocal/src/lib/stores/errors.ts +9 -0
- package/src/ruvocal/src/lib/stores/isAborted.ts +3 -0
- package/src/ruvocal/src/lib/stores/isPro.ts +4 -0
- package/src/ruvocal/src/lib/stores/loading.ts +3 -0
- package/src/ruvocal/src/lib/stores/mcpServers.ts +345 -0
- package/src/ruvocal/src/lib/stores/pendingChatInput.ts +3 -0
- package/src/ruvocal/src/lib/stores/pendingMessage.ts +9 -0
- package/src/ruvocal/src/lib/stores/settings.ts +182 -0
- package/src/ruvocal/src/lib/stores/shareModal.ts +13 -0
- package/src/ruvocal/src/lib/stores/titleUpdate.ts +8 -0
- package/src/ruvocal/src/lib/switchTheme.ts +124 -0
- package/src/ruvocal/src/lib/types/AbortedGeneration.ts +8 -0
- package/src/ruvocal/src/lib/types/Assistant.ts +31 -0
- package/src/ruvocal/src/lib/types/AssistantStats.ts +11 -0
- package/src/ruvocal/src/lib/types/ConfigKey.ts +4 -0
- package/src/ruvocal/src/lib/types/ConvSidebar.ts +9 -0
- package/src/ruvocal/src/lib/types/Conversation.ts +27 -0
- package/src/ruvocal/src/lib/types/ConversationStats.ts +13 -0
- package/src/ruvocal/src/lib/types/Message.ts +41 -0
- package/src/ruvocal/src/lib/types/MessageEvent.ts +10 -0
- package/src/ruvocal/src/lib/types/MessageUpdate.ts +139 -0
- package/src/ruvocal/src/lib/types/MigrationResult.ts +7 -0
- package/src/ruvocal/src/lib/types/Model.ts +23 -0
- package/src/ruvocal/src/lib/types/Report.ts +12 -0
- package/src/ruvocal/src/lib/types/Review.ts +6 -0
- package/src/ruvocal/src/lib/types/Semaphore.ts +19 -0
- package/src/ruvocal/src/lib/types/Session.ts +22 -0
- package/src/ruvocal/src/lib/types/Settings.ts +86 -0
- package/src/ruvocal/src/lib/types/SharedConversation.ts +9 -0
- package/src/ruvocal/src/lib/types/Template.ts +6 -0
- package/src/ruvocal/src/lib/types/Timestamps.ts +4 -0
- package/src/ruvocal/src/lib/types/TokenCache.ts +6 -0
- package/src/ruvocal/src/lib/types/Tool.ts +74 -0
- package/src/ruvocal/src/lib/types/UrlDependency.ts +5 -0
- package/src/ruvocal/src/lib/types/User.ts +14 -0
- package/src/ruvocal/src/lib/utils/PublicConfig.svelte.ts +75 -0
- package/src/ruvocal/src/lib/utils/auth.ts +17 -0
- package/src/ruvocal/src/lib/utils/chunk.ts +33 -0
- package/src/ruvocal/src/lib/utils/cookiesAreEnabled.ts +13 -0
- package/src/ruvocal/src/lib/utils/debounce.ts +17 -0
- package/src/ruvocal/src/lib/utils/deepestChild.ts +6 -0
- package/src/ruvocal/src/lib/utils/favicon.ts +21 -0
- package/src/ruvocal/src/lib/utils/fetchJSON.ts +23 -0
- package/src/ruvocal/src/lib/utils/file2base64.ts +14 -0
- package/src/ruvocal/src/lib/utils/formatUserCount.ts +37 -0
- package/src/ruvocal/src/lib/utils/generationState.spec.ts +75 -0
- package/src/ruvocal/src/lib/utils/generationState.ts +26 -0
- package/src/ruvocal/src/lib/utils/getHref.ts +41 -0
- package/src/ruvocal/src/lib/utils/getReturnFromGenerator.ts +7 -0
- package/src/ruvocal/src/lib/utils/haptics.ts +64 -0
- package/src/ruvocal/src/lib/utils/hashConv.ts +12 -0
- package/src/ruvocal/src/lib/utils/hf.ts +17 -0
- package/src/ruvocal/src/lib/utils/isDesktop.ts +7 -0
- package/src/ruvocal/src/lib/utils/isUrl.ts +8 -0
- package/src/ruvocal/src/lib/utils/isVirtualKeyboard.ts +16 -0
- package/src/ruvocal/src/lib/utils/loadAttachmentsFromUrls.ts +115 -0
- package/src/ruvocal/src/lib/utils/marked.spec.ts +96 -0
- package/src/ruvocal/src/lib/utils/marked.ts +531 -0
- package/src/ruvocal/src/lib/utils/mcpValidation.ts +147 -0
- package/src/ruvocal/src/lib/utils/mergeAsyncGenerators.ts +38 -0
- package/src/ruvocal/src/lib/utils/messageUpdates.spec.ts +262 -0
- package/src/ruvocal/src/lib/utils/messageUpdates.ts +324 -0
- package/src/ruvocal/src/lib/utils/mime.ts +56 -0
- package/src/ruvocal/src/lib/utils/models.ts +14 -0
- package/src/ruvocal/src/lib/utils/parseBlocks.ts +120 -0
- package/src/ruvocal/src/lib/utils/parseIncompleteMarkdown.ts +644 -0
- package/src/ruvocal/src/lib/utils/parseStringToList.ts +10 -0
- package/src/ruvocal/src/lib/utils/randomUuid.ts +14 -0
- package/src/ruvocal/src/lib/utils/searchTokens.ts +33 -0
- package/src/ruvocal/src/lib/utils/sha256.ts +7 -0
- package/src/ruvocal/src/lib/utils/stringifyError.ts +12 -0
- package/src/ruvocal/src/lib/utils/sum.ts +3 -0
- package/src/ruvocal/src/lib/utils/template.spec.ts +59 -0
- package/src/ruvocal/src/lib/utils/template.ts +53 -0
- package/src/ruvocal/src/lib/utils/timeout.ts +9 -0
- package/src/ruvocal/src/lib/utils/toolProgress.spec.ts +46 -0
- package/src/ruvocal/src/lib/utils/toolProgress.ts +11 -0
- package/src/ruvocal/src/lib/utils/tree/addChildren.spec.ts +102 -0
- package/src/ruvocal/src/lib/utils/tree/addChildren.ts +48 -0
- package/src/ruvocal/src/lib/utils/tree/addSibling.spec.ts +81 -0
- package/src/ruvocal/src/lib/utils/tree/addSibling.ts +41 -0
- package/src/ruvocal/src/lib/utils/tree/buildSubtree.spec.ts +110 -0
- package/src/ruvocal/src/lib/utils/tree/buildSubtree.ts +24 -0
- package/src/ruvocal/src/lib/utils/tree/convertLegacyConversation.spec.ts +31 -0
- package/src/ruvocal/src/lib/utils/tree/convertLegacyConversation.ts +36 -0
- package/src/ruvocal/src/lib/utils/tree/isMessageId.spec.ts +15 -0
- package/src/ruvocal/src/lib/utils/tree/isMessageId.ts +5 -0
- package/src/ruvocal/src/lib/utils/tree/tree.d.ts +14 -0
- package/src/ruvocal/src/lib/utils/tree/treeHelpers.spec.ts +167 -0
- package/src/ruvocal/src/lib/utils/updates.ts +39 -0
- package/src/ruvocal/src/lib/utils/urlParams.ts +13 -0
- package/src/ruvocal/src/lib/workers/autopilotWorker.ts +221 -0
- package/src/ruvocal/src/lib/workers/detailFetchWorker.ts +100 -0
- package/src/ruvocal/src/lib/workers/markdownWorker.ts +61 -0
- package/src/ruvocal/src/routes/+error.svelte +20 -0
- package/src/ruvocal/src/routes/+layout.svelte +324 -0
- package/src/ruvocal/src/routes/+layout.ts +91 -0
- package/src/ruvocal/src/routes/+page.svelte +168 -0
- package/src/ruvocal/src/routes/.well-known/oauth-cimd/+server.ts +37 -0
- package/src/ruvocal/src/routes/__debug/openai/+server.ts +21 -0
- package/src/ruvocal/src/routes/admin/export/+server.ts +159 -0
- package/src/ruvocal/src/routes/admin/stats/compute/+server.ts +16 -0
- package/src/ruvocal/src/routes/api/conversation/[id]/+server.ts +40 -0
- package/src/ruvocal/src/routes/api/conversation/[id]/message/[messageId]/+server.ts +42 -0
- package/src/ruvocal/src/routes/api/conversations/+server.ts +48 -0
- package/src/ruvocal/src/routes/api/fetch-url/+server.ts +147 -0
- package/src/ruvocal/src/routes/api/mcp/health/+server.ts +292 -0
- package/src/ruvocal/src/routes/api/mcp/servers/+server.ts +32 -0
- package/src/ruvocal/src/routes/api/models/+server.ts +25 -0
- package/src/ruvocal/src/routes/api/transcribe/+server.ts +104 -0
- package/src/ruvocal/src/routes/api/user/+server.ts +15 -0
- package/src/ruvocal/src/routes/api/user/validate-token/+server.ts +20 -0
- package/src/ruvocal/src/routes/api/v2/conversations/+server.ts +48 -0
- package/src/ruvocal/src/routes/api/v2/conversations/[id]/+server.ts +94 -0
- package/src/ruvocal/src/routes/api/v2/conversations/[id]/message/[messageId]/+server.ts +43 -0
- package/src/ruvocal/src/routes/api/v2/conversations/import-share/+server.ts +23 -0
- package/src/ruvocal/src/routes/api/v2/debug/config/+server.ts +16 -0
- package/src/ruvocal/src/routes/api/v2/debug/refresh/+server.ts +30 -0
- package/src/ruvocal/src/routes/api/v2/export/+server.ts +196 -0
- package/src/ruvocal/src/routes/api/v2/feature-flags/+server.ts +14 -0
- package/src/ruvocal/src/routes/api/v2/models/+server.ts +38 -0
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/+server.ts +8 -0
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/[model]/+server.ts +8 -0
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/[model]/subscribe/+server.ts +28 -0
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/subscribe/+server.ts +28 -0
- package/src/ruvocal/src/routes/api/v2/models/old/+server.ts +7 -0
- package/src/ruvocal/src/routes/api/v2/models/refresh/+server.ts +33 -0
- package/src/ruvocal/src/routes/api/v2/public-config/+server.ts +7 -0
- package/src/ruvocal/src/routes/api/v2/user/+server.ts +17 -0
- package/src/ruvocal/src/routes/api/v2/user/billing-orgs/+server.ts +73 -0
- package/src/ruvocal/src/routes/api/v2/user/reports/+server.ts +17 -0
- package/src/ruvocal/src/routes/api/v2/user/settings/+server.ts +103 -0
- package/src/ruvocal/src/routes/conversation/+server.ts +115 -0
- package/src/ruvocal/src/routes/conversation/[id]/+page.svelte +582 -0
- package/src/ruvocal/src/routes/conversation/[id]/+page.ts +60 -0
- package/src/ruvocal/src/routes/conversation/[id]/+server.ts +736 -0
- package/src/ruvocal/src/routes/conversation/[id]/message/[messageId]/prompt/+server.ts +66 -0
- package/src/ruvocal/src/routes/conversation/[id]/output/[sha256]/+server.ts +58 -0
- package/src/ruvocal/src/routes/conversation/[id]/share/+server.ts +69 -0
- package/src/ruvocal/src/routes/conversation/[id]/stop-generating/+server.ts +35 -0
- package/src/ruvocal/src/routes/healthcheck/+server.ts +3 -0
- package/src/ruvocal/src/routes/login/+server.ts +5 -0
- package/src/ruvocal/src/routes/login/callback/+server.ts +103 -0
- package/src/ruvocal/src/routes/login/callback/updateUser.spec.ts +157 -0
- package/src/ruvocal/src/routes/login/callback/updateUser.ts +215 -0
- package/src/ruvocal/src/routes/logout/+server.ts +18 -0
- package/src/ruvocal/src/routes/metrics/+server.ts +18 -0
- package/src/ruvocal/src/routes/models/+page.svelte +233 -0
- package/src/ruvocal/src/routes/models/[...model]/+page.svelte +161 -0
- package/src/ruvocal/src/routes/models/[...model]/+page.ts +14 -0
- package/src/ruvocal/src/routes/models/[...model]/thumbnail.png/+server.ts +64 -0
- package/src/ruvocal/src/routes/models/[...model]/thumbnail.png/ModelThumbnail.svelte +28 -0
- package/src/ruvocal/src/routes/privacy/+page.svelte +11 -0
- package/src/ruvocal/src/routes/r/[id]/+page.ts +34 -0
- package/src/ruvocal/src/routes/settings/(nav)/+layout.svelte +282 -0
- package/src/ruvocal/src/routes/settings/(nav)/+layout.ts +1 -0
- package/src/ruvocal/src/routes/settings/(nav)/+page.svelte +0 -0
- package/src/ruvocal/src/routes/settings/(nav)/+server.ts +53 -0
- package/src/ruvocal/src/routes/settings/(nav)/[...model]/+page.svelte +464 -0
- package/src/ruvocal/src/routes/settings/(nav)/[...model]/+page.ts +14 -0
- package/src/ruvocal/src/routes/settings/(nav)/application/+page.svelte +362 -0
- package/src/ruvocal/src/routes/settings/+layout.svelte +40 -0
- package/src/ruvocal/src/styles/highlight-js.css +195 -0
- package/src/ruvocal/src/styles/main.css +144 -0
- package/src/ruvocal/static/chatui/apple-touch-icon.png +0 -0
- package/src/ruvocal/static/chatui/favicon-dark.svg +3 -0
- package/src/ruvocal/static/chatui/favicon-dev.svg +3 -0
- package/src/ruvocal/static/chatui/favicon.ico +0 -0
- package/src/ruvocal/static/chatui/favicon.svg +3 -0
- package/src/ruvocal/static/chatui/icon-128x128.png +0 -0
- package/src/ruvocal/static/chatui/icon-144x144.png +0 -0
- package/src/ruvocal/static/chatui/icon-192x192.png +0 -0
- package/src/ruvocal/static/chatui/icon-256x256.png +0 -0
- package/src/ruvocal/static/chatui/icon-36x36.png +0 -0
- package/src/ruvocal/static/chatui/icon-48x48.png +0 -0
- package/src/ruvocal/static/chatui/icon-512x512.png +0 -0
- package/src/ruvocal/static/chatui/icon-72x72.png +0 -0
- package/src/ruvocal/static/chatui/icon-96x96.png +0 -0
- package/src/ruvocal/static/chatui/icon.svg +3 -0
- package/src/ruvocal/static/chatui/logo.svg +7 -0
- package/src/ruvocal/static/chatui/manifest.json +54 -0
- package/src/ruvocal/static/chatui/omni-welcome.gif +0 -0
- package/src/ruvocal/static/chatui/omni-welcome.png +0 -0
- package/src/ruvocal/static/chatui/welcome.js +184 -0
- package/src/ruvocal/static/chatui/welcome.svg +1 -0
- package/src/ruvocal/static/huggingchat/apple-touch-icon.png +0 -0
- package/src/ruvocal/static/huggingchat/assistants-thumbnail.png +0 -0
- package/src/ruvocal/static/huggingchat/castle-example.jpg +0 -0
- package/src/ruvocal/static/huggingchat/favicon-dark.svg +4 -0
- package/src/ruvocal/static/huggingchat/favicon-dev.svg +4 -0
- package/src/ruvocal/static/huggingchat/favicon.ico +0 -0
- package/src/ruvocal/static/huggingchat/favicon.svg +4 -0
- package/src/ruvocal/static/huggingchat/fulltext-logo.svg +2 -0
- package/src/ruvocal/static/huggingchat/icon-128x128.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-144x144.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-192x192.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-256x256.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-36x36.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-48x48.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-512x512.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-72x72.png +0 -0
- package/src/ruvocal/static/huggingchat/icon-96x96.png +0 -0
- package/src/ruvocal/static/huggingchat/icon.svg +4 -0
- package/src/ruvocal/static/huggingchat/logo.svg +4 -0
- package/src/ruvocal/static/huggingchat/manifest.json +54 -0
- package/src/ruvocal/static/huggingchat/omni-welcome.gif +0 -0
- package/src/ruvocal/static/huggingchat/routes.chat.json +226 -0
- package/src/ruvocal/static/huggingchat/thumbnail.png +0 -0
- package/src/ruvocal/static/huggingchat/tools-thumbnail.png +0 -0
- package/src/ruvocal/static/robots.txt +10 -0
- package/src/ruvocal/stub/@reflink/reflink/index.js +0 -0
- package/src/ruvocal/stub/@reflink/reflink/package.json +5 -0
- package/src/ruvocal/svelte.config.js +53 -0
- package/src/ruvocal/tailwind.config.cjs +30 -0
- package/src/ruvocal/tsconfig.json +19 -0
- package/src/ruvocal/vite.config.ts +87 -0
- package/src/scripts/deploy.sh +116 -0
- package/src/scripts/generate-config.js +245 -0
- package/src/scripts/generate-welcome.js +187 -0
- package/src/scripts/package-rvf.sh +116 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { usePublicConfig } from "$lib/utils/PublicConfig.svelte";
|
|
3
|
+
import Modal from "$lib/components/Modal.svelte";
|
|
4
|
+
import ServerCard from "./ServerCard.svelte";
|
|
5
|
+
import AddServerForm from "./AddServerForm.svelte";
|
|
6
|
+
import {
|
|
7
|
+
allMcpServers,
|
|
8
|
+
selectedServerIds,
|
|
9
|
+
enabledServersCount,
|
|
10
|
+
addCustomServer,
|
|
11
|
+
refreshMcpServers,
|
|
12
|
+
healthCheckServer,
|
|
13
|
+
} from "$lib/stores/mcpServers";
|
|
14
|
+
import type { KeyValuePair } from "$lib/types/Tool";
|
|
15
|
+
import IconAddLarge from "~icons/carbon/add-large";
|
|
16
|
+
import IconRefresh from "~icons/carbon/renew";
|
|
17
|
+
import LucideHammer from "~icons/lucide/hammer";
|
|
18
|
+
import IconMCP from "$lib/components/icons/IconMCP.svelte";
|
|
19
|
+
|
|
20
|
+
const publicConfig = usePublicConfig();
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
onclose: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let { onclose }: Props = $props();
|
|
27
|
+
|
|
28
|
+
type View = "list" | "add";
|
|
29
|
+
let currentView = $state<View>("list");
|
|
30
|
+
let isRefreshing = $state(false);
|
|
31
|
+
|
|
32
|
+
const baseServers = $derived($allMcpServers.filter((s) => s.type === "base"));
|
|
33
|
+
const customServers = $derived($allMcpServers.filter((s) => s.type === "custom"));
|
|
34
|
+
const enabledCount = $derived($enabledServersCount);
|
|
35
|
+
|
|
36
|
+
function handleAddServer(serverData: { name: string; url: string; headers?: KeyValuePair[] }) {
|
|
37
|
+
addCustomServer(serverData);
|
|
38
|
+
currentView = "list";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function handleCancel() {
|
|
42
|
+
currentView = "list";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function handleRefresh() {
|
|
46
|
+
if (isRefreshing) return;
|
|
47
|
+
isRefreshing = true;
|
|
48
|
+
try {
|
|
49
|
+
await refreshMcpServers();
|
|
50
|
+
// After refreshing the list, re-run health checks for all known servers
|
|
51
|
+
const servers = $allMcpServers;
|
|
52
|
+
await Promise.allSettled(servers.map((s) => healthCheckServer(s)));
|
|
53
|
+
} finally {
|
|
54
|
+
isRefreshing = false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<Modal width={currentView === "list" ? "w-[800px]" : "w-[600px]"} {onclose} closeButton>
|
|
60
|
+
<div class="p-6">
|
|
61
|
+
<!-- Header -->
|
|
62
|
+
<div class="mb-6">
|
|
63
|
+
<h2 class="mb-1 text-xl font-semibold text-gray-900 dark:text-gray-200">
|
|
64
|
+
{#if currentView === "list"}
|
|
65
|
+
MCP Servers
|
|
66
|
+
{:else}
|
|
67
|
+
Add MCP server
|
|
68
|
+
{/if}
|
|
69
|
+
</h2>
|
|
70
|
+
<p class="text-sm text-gray-600 dark:text-gray-400">
|
|
71
|
+
{#if currentView === "list"}
|
|
72
|
+
Manage MCP servers to extend {publicConfig.PUBLIC_APP_NAME} with external tools.
|
|
73
|
+
{:else}
|
|
74
|
+
Add a custom MCP server to {publicConfig.PUBLIC_APP_NAME}.
|
|
75
|
+
{/if}
|
|
76
|
+
</p>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- Content -->
|
|
80
|
+
{#if currentView === "list"}
|
|
81
|
+
<div
|
|
82
|
+
class="mb-6 flex justify-between rounded-lg p-4 max-sm:flex-col max-sm:gap-4 sm:items-center {!enabledCount
|
|
83
|
+
? 'bg-gray-100 dark:bg-white/5'
|
|
84
|
+
: 'bg-blue-50 dark:bg-blue-900/10'}"
|
|
85
|
+
>
|
|
86
|
+
<div class="flex items-center gap-3">
|
|
87
|
+
<div
|
|
88
|
+
class="flex size-10 items-center justify-center rounded-xl bg-blue-500/10"
|
|
89
|
+
class:grayscale={!enabledCount}
|
|
90
|
+
>
|
|
91
|
+
<IconMCP classNames="size-8 text-blue-600 dark:text-blue-500" />
|
|
92
|
+
</div>
|
|
93
|
+
<div>
|
|
94
|
+
<p class="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
95
|
+
{$allMcpServers.length}
|
|
96
|
+
{$allMcpServers.length === 1 ? "server" : "servers"} configured
|
|
97
|
+
</p>
|
|
98
|
+
<p class="text-xs text-gray-600 dark:text-gray-400">
|
|
99
|
+
{enabledCount} enabled
|
|
100
|
+
</p>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="flex gap-2">
|
|
105
|
+
<button
|
|
106
|
+
onclick={handleRefresh}
|
|
107
|
+
disabled={isRefreshing}
|
|
108
|
+
class="btn gap-1.5 rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700"
|
|
109
|
+
>
|
|
110
|
+
<IconRefresh class="size-4 {isRefreshing ? 'animate-spin' : ''}" />
|
|
111
|
+
{isRefreshing ? "Refreshing…" : "Refresh"}
|
|
112
|
+
</button>
|
|
113
|
+
<button
|
|
114
|
+
onclick={() => (currentView = "add")}
|
|
115
|
+
class="btn flex items-center gap-0.5 rounded-lg bg-blue-600 py-1.5 pl-2 pr-3 text-sm font-medium text-white hover:bg-blue-600"
|
|
116
|
+
>
|
|
117
|
+
<IconAddLarge class="size-4" />
|
|
118
|
+
Add Server
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="space-y-5">
|
|
123
|
+
<!-- Base Servers -->
|
|
124
|
+
{#if baseServers.length > 0}
|
|
125
|
+
<div>
|
|
126
|
+
<h3 class="mb-3 text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
127
|
+
Base Servers ({baseServers.length})
|
|
128
|
+
</h3>
|
|
129
|
+
<div class="grid grid-cols-1 gap-3 md:grid-cols-2">
|
|
130
|
+
{#each baseServers as server (server.id)}
|
|
131
|
+
<ServerCard {server} isSelected={$selectedServerIds.has(server.id)} />
|
|
132
|
+
{/each}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
{/if}
|
|
136
|
+
|
|
137
|
+
<!-- Custom Servers -->
|
|
138
|
+
<div>
|
|
139
|
+
<h3 class="mb-3 text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
140
|
+
Custom Servers ({customServers.length})
|
|
141
|
+
</h3>
|
|
142
|
+
{#if customServers.length === 0}
|
|
143
|
+
<div
|
|
144
|
+
class="flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 p-8 dark:border-gray-700"
|
|
145
|
+
>
|
|
146
|
+
<LucideHammer class="mb-3 size-12 text-gray-400" />
|
|
147
|
+
<p class="mb-1 text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
148
|
+
No custom servers yet
|
|
149
|
+
</p>
|
|
150
|
+
<p class="mb-4 text-xs text-gray-600 dark:text-gray-400">
|
|
151
|
+
Add your own MCP servers with custom tools
|
|
152
|
+
</p>
|
|
153
|
+
<button
|
|
154
|
+
onclick={() => (currentView = "add")}
|
|
155
|
+
class="flex items-center gap-1.5 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-600"
|
|
156
|
+
>
|
|
157
|
+
<IconAddLarge class="size-4" />
|
|
158
|
+
Add Your First Server
|
|
159
|
+
</button>
|
|
160
|
+
</div>
|
|
161
|
+
{:else}
|
|
162
|
+
<div class="grid grid-cols-1 gap-3 md:grid-cols-2">
|
|
163
|
+
{#each customServers as server (server.id)}
|
|
164
|
+
<ServerCard {server} isSelected={$selectedServerIds.has(server.id)} />
|
|
165
|
+
{/each}
|
|
166
|
+
</div>
|
|
167
|
+
{/if}
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<!-- Help Text -->
|
|
171
|
+
<div class="rounded-lg bg-gray-50 p-4 dark:bg-gray-700">
|
|
172
|
+
<h4 class="mb-2 text-sm font-medium text-gray-900 dark:text-gray-100">💡 Quick Tips</h4>
|
|
173
|
+
<ul class="space-y-1 text-xs text-gray-600 dark:text-gray-400">
|
|
174
|
+
<li>• Only connect to servers you trust</li>
|
|
175
|
+
<li>• Enable servers to make their tools available in chat</li>
|
|
176
|
+
<li>• Use the Health Check button to verify server connectivity</li>
|
|
177
|
+
<li>• You can add HTTP headers for authentication when required</li>
|
|
178
|
+
</ul>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
{:else if currentView === "add"}
|
|
182
|
+
<AddServerForm onsubmit={handleAddServer} oncancel={handleCancel} />
|
|
183
|
+
{/if}
|
|
184
|
+
</div>
|
|
185
|
+
</Modal>
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { MCPServer } from "$lib/types/Tool";
|
|
3
|
+
import { toggleServer, healthCheckServer, deleteCustomServer } from "$lib/stores/mcpServers";
|
|
4
|
+
import IconCheckmark from "~icons/carbon/checkmark-filled";
|
|
5
|
+
import IconWarning from "~icons/carbon/warning-filled";
|
|
6
|
+
import IconPending from "~icons/carbon/pending-filled";
|
|
7
|
+
import IconRefresh from "~icons/carbon/renew";
|
|
8
|
+
import IconTrash from "~icons/carbon/trash-can";
|
|
9
|
+
import LucideHammer from "~icons/lucide/hammer";
|
|
10
|
+
import IconSettings from "~icons/carbon/settings";
|
|
11
|
+
import Switch from "$lib/components/Switch.svelte";
|
|
12
|
+
import { getMcpServerFaviconUrl } from "$lib/utils/favicon";
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
server: MCPServer;
|
|
16
|
+
isSelected: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { server, isSelected }: Props = $props();
|
|
20
|
+
|
|
21
|
+
let isLoadingHealth = $state(false);
|
|
22
|
+
|
|
23
|
+
// Show a quick-access link ONLY for the exact HF MCP login endpoint
|
|
24
|
+
import { isStrictHfMcpLogin as isStrictHfMcpLoginUrl } from "$lib/utils/hf";
|
|
25
|
+
const isHfMcp = $derived.by(() => isStrictHfMcpLoginUrl(server.url));
|
|
26
|
+
|
|
27
|
+
const statusInfo = $derived.by(() => {
|
|
28
|
+
switch (server.status) {
|
|
29
|
+
case "connected":
|
|
30
|
+
return {
|
|
31
|
+
label: "Connected",
|
|
32
|
+
color: "text-green-600 dark:text-green-400",
|
|
33
|
+
bgColor: "bg-green-100 dark:bg-green-900/20",
|
|
34
|
+
icon: IconCheckmark,
|
|
35
|
+
};
|
|
36
|
+
case "connecting":
|
|
37
|
+
return {
|
|
38
|
+
label: "Connecting...",
|
|
39
|
+
color: "text-blue-600 dark:text-blue-400",
|
|
40
|
+
bgColor: "bg-blue-100 dark:bg-blue-900/20",
|
|
41
|
+
icon: IconPending,
|
|
42
|
+
};
|
|
43
|
+
case "error":
|
|
44
|
+
return {
|
|
45
|
+
label: "Error",
|
|
46
|
+
color: "text-red-600 dark:text-red-400",
|
|
47
|
+
bgColor: "bg-red-100 dark:bg-red-900/20",
|
|
48
|
+
icon: IconWarning,
|
|
49
|
+
};
|
|
50
|
+
case "disconnected":
|
|
51
|
+
default:
|
|
52
|
+
return {
|
|
53
|
+
label: "Unknown",
|
|
54
|
+
color: "text-gray-600 dark:text-gray-400",
|
|
55
|
+
bgColor: "bg-gray-100 dark:bg-gray-700",
|
|
56
|
+
icon: IconPending,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Switch setter handles enable/disable (simple, idiomatic)
|
|
62
|
+
function setEnabled(v: boolean) {
|
|
63
|
+
if (v === isSelected) return;
|
|
64
|
+
toggleServer(server.id);
|
|
65
|
+
if (v && server.status !== "connected") handleHealthCheck();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function handleHealthCheck() {
|
|
69
|
+
isLoadingHealth = true;
|
|
70
|
+
try {
|
|
71
|
+
await healthCheckServer(server);
|
|
72
|
+
} finally {
|
|
73
|
+
isLoadingHealth = false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function handleDelete() {
|
|
78
|
+
deleteCustomServer(server.id);
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<div
|
|
83
|
+
class="rounded-lg border bg-gradient-to-br transition-colors {isSelected
|
|
84
|
+
? 'border-blue-600/20 bg-blue-50 from-blue-500/5 to-transparent dark:border-blue-700/60 dark:bg-blue-900/10 dark:from-blue-900/20'
|
|
85
|
+
: 'border-gray-200 bg-white from-black/5 dark:border-gray-700 dark:bg-gray-800 dark:from-white/5'}"
|
|
86
|
+
>
|
|
87
|
+
<div class="px-4 py-3.5">
|
|
88
|
+
<!-- Header -->
|
|
89
|
+
<div class="mb-3 flex items-start justify-between gap-3">
|
|
90
|
+
<div class="min-w-0 flex-1">
|
|
91
|
+
<div class="mb-0.5 flex items-center gap-2">
|
|
92
|
+
<img
|
|
93
|
+
src={getMcpServerFaviconUrl(server.url)}
|
|
94
|
+
alt=""
|
|
95
|
+
class="size-4 flex-shrink-0 rounded"
|
|
96
|
+
/>
|
|
97
|
+
<h3 class="truncate font-semibold text-gray-900 dark:text-gray-100">
|
|
98
|
+
{server.name}
|
|
99
|
+
</h3>
|
|
100
|
+
</div>
|
|
101
|
+
<p class="truncate text-sm text-gray-600 dark:text-gray-400">
|
|
102
|
+
{server.url}
|
|
103
|
+
</p>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!-- Enable Switch (function binding per Svelte 5 docs) -->
|
|
107
|
+
<Switch name={`enable-${server.id}`} bind:checked={() => isSelected, setEnabled} />
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<!-- Status -->
|
|
111
|
+
{#if server.status}
|
|
112
|
+
<div class="mb-2 flex items-center gap-2">
|
|
113
|
+
<span
|
|
114
|
+
class="inline-flex items-center gap-1 rounded-full {statusInfo.bgColor} py-0.5 pl-1.5 pr-2 text-xs font-medium {statusInfo.color}"
|
|
115
|
+
>
|
|
116
|
+
{#if server.status === "connected"}
|
|
117
|
+
<IconCheckmark class="size-3" />
|
|
118
|
+
{:else if server.status === "connecting"}
|
|
119
|
+
<IconPending class="size-3" />
|
|
120
|
+
{:else if server.status === "error"}
|
|
121
|
+
<IconWarning class="size-3" />
|
|
122
|
+
{:else}
|
|
123
|
+
<IconPending class="size-3" />
|
|
124
|
+
{/if}
|
|
125
|
+
{statusInfo.label}
|
|
126
|
+
</span>
|
|
127
|
+
|
|
128
|
+
{#if server.tools && server.tools.length > 0}
|
|
129
|
+
<span class="inline-flex items-center gap-1 text-xs text-gray-600 dark:text-gray-400">
|
|
130
|
+
<LucideHammer class="size-3" />
|
|
131
|
+
{server.tools.length}
|
|
132
|
+
{server.tools.length === 1 ? "tool" : "tools"}
|
|
133
|
+
</span>
|
|
134
|
+
{/if}
|
|
135
|
+
</div>
|
|
136
|
+
{/if}
|
|
137
|
+
|
|
138
|
+
<!-- Error Message -->
|
|
139
|
+
{#if server.errorMessage}
|
|
140
|
+
<div class="mb-2 flex items-center gap-2">
|
|
141
|
+
<div
|
|
142
|
+
class="line-clamp-6 break-words rounded bg-red-50 px-2 py-1 text-xs text-red-800 dark:bg-red-900/20 dark:text-red-200"
|
|
143
|
+
>
|
|
144
|
+
{server.errorMessage}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
{/if}
|
|
148
|
+
|
|
149
|
+
<!-- Actions -->
|
|
150
|
+
<div class="flex flex-wrap gap-1">
|
|
151
|
+
<button
|
|
152
|
+
onclick={handleHealthCheck}
|
|
153
|
+
disabled={isLoadingHealth}
|
|
154
|
+
class="flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white px-2.5 py-[.29rem] text-xs font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
|
|
155
|
+
>
|
|
156
|
+
<IconRefresh class="size-3 {isLoadingHealth ? 'animate-spin' : ''}" />
|
|
157
|
+
Health Check
|
|
158
|
+
</button>
|
|
159
|
+
|
|
160
|
+
{#if isHfMcp}
|
|
161
|
+
<a
|
|
162
|
+
href="https://huggingface.co/settings/mcp"
|
|
163
|
+
target="_blank"
|
|
164
|
+
rel="noopener noreferrer"
|
|
165
|
+
class="flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white px-2.5 py-[.29rem] text-xs font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
|
|
166
|
+
aria-label="Open Hugging Face MCP settings"
|
|
167
|
+
>
|
|
168
|
+
<IconSettings class="size-3" />
|
|
169
|
+
Settings
|
|
170
|
+
</a>
|
|
171
|
+
{/if}
|
|
172
|
+
|
|
173
|
+
{#if server.type === "custom"}
|
|
174
|
+
<button
|
|
175
|
+
onclick={handleDelete}
|
|
176
|
+
class="flex items-center gap-1.5 rounded-lg border border-red-500/15 bg-red-50 px-2.5 py-[.29rem] text-xs font-medium text-red-600 hover:bg-red-100 dark:border-red-500/25 dark:bg-red-900/30 dark:text-red-400 dark:hover:bg-red-900/50"
|
|
177
|
+
>
|
|
178
|
+
<IconTrash class="size-3" />
|
|
179
|
+
Delete
|
|
180
|
+
</button>
|
|
181
|
+
{/if}
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<!-- Tools List (Expandable) -->
|
|
185
|
+
{#if server.tools && server.tools.length > 0}
|
|
186
|
+
<details class="mt-3">
|
|
187
|
+
<summary class="cursor-pointer text-xs font-medium text-gray-700 dark:text-gray-300">
|
|
188
|
+
Available Tools ({server.tools.length})
|
|
189
|
+
</summary>
|
|
190
|
+
<ul class="mt-2 space-y-1 text-xs">
|
|
191
|
+
{#each server.tools as tool}
|
|
192
|
+
<li class="text-gray-600 dark:text-gray-400">
|
|
193
|
+
<span class="font-medium text-gray-900 dark:text-gray-100">{tool.name}</span>
|
|
194
|
+
{#if tool.description}
|
|
195
|
+
<span class="text-gray-500 dark:text-gray-500">- {tool.description}</span>
|
|
196
|
+
{/if}
|
|
197
|
+
</li>
|
|
198
|
+
{/each}
|
|
199
|
+
</ul>
|
|
200
|
+
</details>
|
|
201
|
+
{/if}
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CarbonPause from "~icons/carbon/pause";
|
|
3
|
+
import CarbonPlay from "~icons/carbon/play";
|
|
4
|
+
interface Props {
|
|
5
|
+
src: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { src, name }: Props = $props();
|
|
10
|
+
|
|
11
|
+
let time = $state(0);
|
|
12
|
+
let duration = $state(0);
|
|
13
|
+
let paused = $state(true);
|
|
14
|
+
|
|
15
|
+
function format(time: number) {
|
|
16
|
+
if (isNaN(time)) return "...";
|
|
17
|
+
|
|
18
|
+
const minutes = Math.floor(time / 60);
|
|
19
|
+
const seconds = Math.floor(time % 60);
|
|
20
|
+
|
|
21
|
+
return `${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function seek(e: PointerEvent) {
|
|
25
|
+
if (!e.currentTarget) return;
|
|
26
|
+
const { left, width } = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
27
|
+
|
|
28
|
+
let p = (e.clientX - left) / width;
|
|
29
|
+
if (p < 0) p = 0;
|
|
30
|
+
if (p > 1) p = 1;
|
|
31
|
+
|
|
32
|
+
time = p * duration;
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<div
|
|
37
|
+
class="flex h-14 w-72 items-center gap-4 rounded-2xl border border-gray-200 bg-white p-2.5 text-gray-600 shadow-sm transition-all dark:border-gray-800 dark:bg-gray-900 dark:text-gray-300"
|
|
38
|
+
>
|
|
39
|
+
<audio
|
|
40
|
+
{src}
|
|
41
|
+
bind:currentTime={time}
|
|
42
|
+
bind:duration
|
|
43
|
+
bind:paused
|
|
44
|
+
preload="metadata"
|
|
45
|
+
onended={() => {
|
|
46
|
+
time = 0;
|
|
47
|
+
}}
|
|
48
|
+
></audio>
|
|
49
|
+
|
|
50
|
+
<button
|
|
51
|
+
class="mx-auto my-auto aspect-square size-8 rounded-full border border-gray-400 bg-gray-100 dark:border-gray-800 dark:bg-gray-700"
|
|
52
|
+
aria-label={paused ? "play" : "pause"}
|
|
53
|
+
onclick={() => (paused = !paused)}
|
|
54
|
+
>
|
|
55
|
+
{#if paused}
|
|
56
|
+
<CarbonPlay class="mx-auto my-auto text-gray-600 dark:text-gray-300" />
|
|
57
|
+
{:else}
|
|
58
|
+
<CarbonPause class="mx-auto my-auto text-gray-600 dark:text-gray-300" />
|
|
59
|
+
{/if}
|
|
60
|
+
</button>
|
|
61
|
+
<div class="overflow-hidden">
|
|
62
|
+
<div class="truncate font-medium">{name}</div>
|
|
63
|
+
{#if duration !== Infinity}
|
|
64
|
+
<div class="flex items-center gap-2">
|
|
65
|
+
<span class="text-xs">{format(time)}</span>
|
|
66
|
+
<div
|
|
67
|
+
class="relative h-2 flex-1 rounded-full bg-gray-200 dark:bg-gray-700"
|
|
68
|
+
onpointerdown={() => {
|
|
69
|
+
paused = true;
|
|
70
|
+
}}
|
|
71
|
+
onpointerup={seek}
|
|
72
|
+
>
|
|
73
|
+
<div
|
|
74
|
+
class="absolute inset-0 h-full bg-gray-400 dark:bg-gray-600"
|
|
75
|
+
style="width: {(time / duration) * 100}%"
|
|
76
|
+
></div>
|
|
77
|
+
</div>
|
|
78
|
+
<span class="text-xs">{duration ? format(duration) : "--:--"}</span>
|
|
79
|
+
</div>
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount, onDestroy } from "svelte";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
frequencyData: Uint8Array;
|
|
6
|
+
minHeight?: number;
|
|
7
|
+
maxHeight?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { frequencyData, minHeight = 4, maxHeight = 40 }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const PILL_WIDTH = 2; // w-0.5 = 2px
|
|
13
|
+
const PILL_GAP = 2;
|
|
14
|
+
const SAMPLE_INTERVAL_MS = 50; // Sample every 50ms (~20 samples/sec)
|
|
15
|
+
|
|
16
|
+
let containerRef: HTMLDivElement | undefined = $state();
|
|
17
|
+
let timeline: number[] = $state([]);
|
|
18
|
+
let pillCount = $state(60); // Default, will be calculated from container width
|
|
19
|
+
let intervalId: ReturnType<typeof setInterval> | undefined;
|
|
20
|
+
let smoothedAmplitude = 0;
|
|
21
|
+
|
|
22
|
+
// Calculate average amplitude from frequency data
|
|
23
|
+
function getAmplitude(): number {
|
|
24
|
+
if (!frequencyData.length) return 0;
|
|
25
|
+
let sum = 0;
|
|
26
|
+
for (let i = 0; i < frequencyData.length; i++) {
|
|
27
|
+
sum += frequencyData[i];
|
|
28
|
+
}
|
|
29
|
+
return sum / frequencyData.length / 255; // Normalize to 0-1
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function addSample() {
|
|
33
|
+
const rawAmplitude = getAmplitude();
|
|
34
|
+
// Smooth the amplitude for less jittery visualization
|
|
35
|
+
smoothedAmplitude = smoothedAmplitude * 0.3 + rawAmplitude * 0.7;
|
|
36
|
+
|
|
37
|
+
// Boost amplitude by 1.5x and apply slight curve for better visibility
|
|
38
|
+
const boostedAmplitude = Math.min(1, Math.pow(smoothedAmplitude * 1.5, 0.85));
|
|
39
|
+
|
|
40
|
+
const height = minHeight + boostedAmplitude * (maxHeight - minHeight);
|
|
41
|
+
|
|
42
|
+
// Push new sample, keep only pillCount samples (sliding window)
|
|
43
|
+
timeline = [...timeline, height].slice(-pillCount);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function calculatePillCount() {
|
|
47
|
+
if (containerRef) {
|
|
48
|
+
const width = containerRef.clientWidth;
|
|
49
|
+
pillCount = Math.max(20, Math.floor(width / (PILL_WIDTH + PILL_GAP)));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
onMount(() => {
|
|
54
|
+
calculatePillCount();
|
|
55
|
+
|
|
56
|
+
// Initialize timeline with minimum height dots
|
|
57
|
+
timeline = Array(pillCount).fill(minHeight);
|
|
58
|
+
|
|
59
|
+
// Start sampling at fixed intervals
|
|
60
|
+
intervalId = setInterval(addSample, SAMPLE_INTERVAL_MS);
|
|
61
|
+
|
|
62
|
+
// Handle resize
|
|
63
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
64
|
+
const oldCount = pillCount;
|
|
65
|
+
calculatePillCount();
|
|
66
|
+
// Adjust timeline buffer if container size changed
|
|
67
|
+
if (pillCount > oldCount) {
|
|
68
|
+
// Pad with min height on the left
|
|
69
|
+
timeline = [...Array(pillCount - oldCount).fill(minHeight), ...timeline];
|
|
70
|
+
} else if (pillCount < oldCount) {
|
|
71
|
+
timeline = timeline.slice(-pillCount);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (containerRef) {
|
|
76
|
+
resizeObserver.observe(containerRef);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return () => {
|
|
80
|
+
resizeObserver.disconnect();
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
onDestroy(() => {
|
|
85
|
+
if (intervalId) clearInterval(intervalId);
|
|
86
|
+
});
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<div bind:this={containerRef} class="flex h-12 w-full items-center justify-start gap-[2px]">
|
|
90
|
+
{#each timeline as height, i (i)}
|
|
91
|
+
<div
|
|
92
|
+
class="w-0.5 shrink-0 rounded-full bg-gray-400 dark:bg-white/60"
|
|
93
|
+
style="height: {Math.max(minHeight, Math.round(height))}px;"
|
|
94
|
+
></div>
|
|
95
|
+
{/each}
|
|
96
|
+
</div>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { RouterExample } from "./routerExamples";
|
|
2
|
+
|
|
3
|
+
// Examples that showcase MCP tool capabilities (web search, Hugging Face, etc.)
|
|
4
|
+
export const mcpExamples: RouterExample[] = [
|
|
5
|
+
{
|
|
6
|
+
title: "Generate an image",
|
|
7
|
+
prompt: "Generate an image of a zebra in front of a volcanic eruption",
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: "Latest world news",
|
|
11
|
+
prompt: "What is the latest world news?",
|
|
12
|
+
followUps: [
|
|
13
|
+
{
|
|
14
|
+
title: "Tech focus",
|
|
15
|
+
prompt: "What about technology news?",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: "San Francisco",
|
|
19
|
+
prompt: "What's happening in San Francisco?",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: "vs last week",
|
|
23
|
+
prompt: "How does this compare to last week's news?",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
title: "Trending models",
|
|
29
|
+
prompt: "What are the top trending models on Hugging Face?",
|
|
30
|
+
followUps: [
|
|
31
|
+
{
|
|
32
|
+
title: "Text generation",
|
|
33
|
+
prompt: "What about text generation models?",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
title: "Image generation",
|
|
37
|
+
prompt: "What about text-to-image models?",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
title: "How to use",
|
|
41
|
+
prompt: "Show me how to use the most popular one",
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Plan a trip",
|
|
47
|
+
prompt: "Things to do in Tokyo next week",
|
|
48
|
+
followUps: [
|
|
49
|
+
{
|
|
50
|
+
title: "Transport & prices",
|
|
51
|
+
prompt: "How do I get around and how much will it cost?",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: "Weather",
|
|
55
|
+
prompt: "What's the weather like in Tokyo next week?",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: "Meet people",
|
|
59
|
+
prompt: "Where can I meet new people and make friends?",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: "Compare technologies",
|
|
65
|
+
prompt: "Search the web to compare React, Vue, and Svelte for building web apps in 2025",
|
|
66
|
+
followUps: [
|
|
67
|
+
{
|
|
68
|
+
title: "Performance benchmarks",
|
|
69
|
+
prompt: "Search for recent performance benchmarks comparing these frameworks",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: "Job market",
|
|
73
|
+
prompt: "Search for job market trends for each of these frameworks",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
title: "Migration guides",
|
|
77
|
+
prompt: "Search for guides on migrating from React to Svelte",
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: "Find a dataset",
|
|
83
|
+
prompt: "Find datasets on Hugging Face for training a sentiment analysis model",
|
|
84
|
+
followUps: [
|
|
85
|
+
{
|
|
86
|
+
title: "Dataset details",
|
|
87
|
+
prompt: "Tell me more about the largest dataset - its size, format, and how to load it",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
title: "Find models",
|
|
91
|
+
prompt: "Find pre-trained models that were trained on this dataset",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
title: "Code snippet",
|
|
95
|
+
prompt: "Show me how to load and preprocess this dataset with the datasets library",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: "Gift ideas",
|
|
101
|
+
prompt: "Search for unique gift ideas for someone who loves cooking",
|
|
102
|
+
followUps: [
|
|
103
|
+
{
|
|
104
|
+
title: "Budget options",
|
|
105
|
+
prompt: "Search for gift ideas under $50",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
title: "Top rated",
|
|
109
|
+
prompt: "Search for the top-rated cooking gadgets of this year",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
title: "DIY gifts",
|
|
113
|
+
prompt: "Search for homemade gift ideas for cooking enthusiasts",
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
title: "Learn something new",
|
|
119
|
+
prompt: "Search for the best resources to learn Rust programming in 2025",
|
|
120
|
+
followUps: [
|
|
121
|
+
{
|
|
122
|
+
title: "Project ideas",
|
|
123
|
+
prompt: "Search for beginner Rust project ideas to practice with",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
title: "Find tools",
|
|
127
|
+
prompt: "Search for the most popular Rust tools and libraries I should know about",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
title: "Community",
|
|
131
|
+
prompt: "Search for Rust communities and forums where I can ask questions",
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
];
|