ruflo 3.10.46 → 3.11.0
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/README.md +412 -412
- package/bin/ruflo.js +77 -77
- package/package.json +113 -113
- package/src/chat-ui/Dockerfile +25 -25
- package/src/chat-ui/patch-mcp-url-safety.sh +28 -28
- package/src/config/config.example.json +76 -76
- package/src/mcp-bridge/Dockerfile +45 -45
- package/src/mcp-bridge/index.js +1692 -1692
- package/src/mcp-bridge/mcp-stdio-kernel.js +159 -159
- package/src/mcp-bridge/package.json +17 -17
- package/src/mcp-bridge/test-harness.js +470 -470
- package/src/nginx/Dockerfile +10 -10
- package/src/nginx/nginx.conf +67 -67
- package/src/nginx/static/favicon-dark.svg +4 -4
- package/src/nginx/static/favicon.svg +4 -4
- package/src/nginx/static/icon.svg +5 -5
- package/src/nginx/static/logo.svg +9 -9
- package/src/nginx/static/manifest.json +22 -22
- package/src/nginx/static/welcome.js +184 -184
- package/src/ruvocal/.claude/skills/add-model-descriptions/SKILL.md +73 -73
- package/src/ruvocal/.claude-flow/daemon-state.json +135 -0
- package/src/ruvocal/.claude-flow/data/pending-insights.jsonl +0 -0
- package/src/ruvocal/.claude-flow/data/ranked-context.json +5 -0
- package/src/ruvocal/.claude-flow/logs/daemon.log +31 -0
- package/src/ruvocal/.claude-flow/logs/headless/audit_1777949411822_juxau0_prompt.log +989 -0
- package/src/ruvocal/.claude-flow/logs/headless/audit_1777949411822_juxau0_result.log +67 -0
- package/src/ruvocal/.claude-flow/logs/headless/audit_1777950042278_jvj5xq_prompt.log +989 -0
- package/src/ruvocal/.claude-flow/logs/headless/audit_1777950042278_jvj5xq_result.log +93 -0
- package/src/ruvocal/.claude-flow/logs/headless/optimize_1777949531823_yt5yc2_prompt.log +1498 -0
- package/src/ruvocal/.claude-flow/logs/headless/optimize_1777949531823_yt5yc2_result.log +93 -0
- package/src/ruvocal/.claude-flow/logs/headless/testgaps_1777949771821_elw1j4_prompt.log +1498 -0
- package/src/ruvocal/.claude-flow/logs/headless/testgaps_1777949771821_elw1j4_result.log +100 -0
- package/src/ruvocal/.claude-flow/metrics/codebase-map.json +11 -0
- package/src/ruvocal/.claude-flow/metrics/consolidation.json +6 -0
- package/src/ruvocal/.claude-flow/neural/stats.json +6 -0
- package/src/ruvocal/.claude-flow/sessions/current.json +13 -0
- package/src/ruvocal/.devcontainer/Dockerfile +9 -9
- package/src/ruvocal/.devcontainer/devcontainer.json +36 -36
- package/src/ruvocal/.dockerignore +16 -16
- package/src/ruvocal/.eslintignore +13 -13
- package/src/ruvocal/.eslintrc.cjs +45 -45
- package/src/ruvocal/.gcloudignore +18 -18
- package/src/ruvocal/.github/ISSUE_TEMPLATE/bug-report--chat-ui-.md +43 -43
- package/src/ruvocal/.github/ISSUE_TEMPLATE/config-support.md +9 -9
- package/src/ruvocal/.github/ISSUE_TEMPLATE/feature-request--chat-ui-.md +17 -17
- package/src/ruvocal/.github/ISSUE_TEMPLATE/huggingchat.md +11 -11
- package/src/ruvocal/.github/release.yml +16 -16
- package/src/ruvocal/.github/workflows/build-docs.yml +18 -18
- package/src/ruvocal/.github/workflows/build-image.yml +142 -142
- package/src/ruvocal/.github/workflows/build-pr-docs.yml +20 -20
- package/src/ruvocal/.github/workflows/deploy-dev.yml +63 -63
- package/src/ruvocal/.github/workflows/deploy-prod.yml +78 -78
- package/src/ruvocal/.github/workflows/lint-and-test.yml +84 -84
- package/src/ruvocal/.github/workflows/slugify.yaml +72 -72
- package/src/ruvocal/.github/workflows/trufflehog.yml +17 -17
- package/src/ruvocal/.github/workflows/upload-pr-documentation.yml +16 -16
- package/src/ruvocal/.husky/lint-stage-config.js +4 -4
- package/src/ruvocal/.husky/pre-commit +2 -2
- package/src/ruvocal/.prettierignore +14 -14
- package/src/ruvocal/.prettierrc +7 -7
- package/src/ruvocal/.swarm/attestation.db +0 -0
- package/src/ruvocal/.swarm/hnsw.index +0 -0
- package/src/ruvocal/.swarm/hnsw.metadata.json +1 -0
- package/src/ruvocal/.swarm/memory.db +0 -0
- package/src/ruvocal/.swarm/schema.sql +305 -0
- package/src/ruvocal/CLAUDE.md +126 -126
- package/src/ruvocal/Dockerfile +96 -96
- package/src/ruvocal/LICENSE +202 -202
- package/src/ruvocal/PRIVACY.md +41 -41
- package/src/ruvocal/README.md +164 -164
- package/src/ruvocal/chart/Chart.yaml +5 -5
- package/src/ruvocal/chart/env/dev.yaml +260 -260
- package/src/ruvocal/chart/env/prod.yaml +273 -273
- package/src/ruvocal/chart/templates/_helpers.tpl +22 -22
- package/src/ruvocal/chart/templates/config.yaml +10 -10
- package/src/ruvocal/chart/templates/deployment.yaml +81 -81
- package/src/ruvocal/chart/templates/hpa.yaml +45 -45
- package/src/ruvocal/chart/templates/infisical.yaml +24 -24
- package/src/ruvocal/chart/templates/ingress-internal.yaml +32 -32
- package/src/ruvocal/chart/templates/ingress.yaml +32 -32
- package/src/ruvocal/chart/templates/network-policy.yaml +36 -36
- package/src/ruvocal/chart/templates/service-account.yaml +13 -13
- package/src/ruvocal/chart/templates/service-monitor.yaml +17 -17
- package/src/ruvocal/chart/templates/service.yaml +21 -21
- package/src/ruvocal/chart/values.yaml +73 -73
- package/src/ruvocal/cloudbuild.yaml +68 -68
- package/src/ruvocal/config/branding.env.example +19 -19
- package/src/ruvocal/docker-compose.yml +21 -21
- package/src/ruvocal/docs/adr/ADR-029-HUGGINGFACE-CHAT-UI-CLOUD-RUN.md +1236 -1236
- package/src/ruvocal/docs/adr/ADR-033-RUVECTOR-RUFLO-MCP-INTEGRATION.md +111 -111
- package/src/ruvocal/docs/adr/ADR-034-OPTIONAL-MCP-BACKENDS.md +117 -117
- package/src/ruvocal/docs/adr/ADR-035-MCP-TOOL-GROUPS.md +186 -186
- package/src/ruvocal/docs/adr/ADR-037-AUTOPILOT-CHAT-MODE.md +1500 -1500
- package/src/ruvocal/docs/adr/ADR-038-RUVOCAL-FORK.md +286 -286
- package/src/ruvocal/docs/source/_toctree.yml +30 -30
- package/src/ruvocal/docs/source/configuration/common-issues.md +38 -38
- package/src/ruvocal/docs/source/configuration/llm-router.md +105 -105
- package/src/ruvocal/docs/source/configuration/mcp-tools.md +84 -84
- package/src/ruvocal/docs/source/configuration/metrics.md +9 -9
- package/src/ruvocal/docs/source/configuration/open-id.md +57 -57
- package/src/ruvocal/docs/source/configuration/overview.md +89 -89
- package/src/ruvocal/docs/source/configuration/theming.md +20 -20
- package/src/ruvocal/docs/source/developing/architecture.md +48 -48
- package/src/ruvocal/docs/source/index.md +53 -53
- package/src/ruvocal/docs/source/installation/docker.md +43 -43
- package/src/ruvocal/docs/source/installation/helm.md +43 -43
- package/src/ruvocal/docs/source/installation/local.md +62 -62
- package/src/ruvocal/entrypoint.sh +18 -18
- package/src/ruvocal/mcp-bridge/Dockerfile +45 -45
- package/src/ruvocal/mcp-bridge/cloudbuild.yaml +49 -49
- package/src/ruvocal/mcp-bridge/index.js +1902 -1902
- package/src/ruvocal/mcp-bridge/mcp-stdio-kernel.js +159 -159
- package/src/ruvocal/mcp-bridge/package-lock.json +762 -762
- package/src/ruvocal/mcp-bridge/package.json +17 -17
- package/src/ruvocal/mcp-bridge/test-harness.js +470 -470
- package/src/ruvocal/package-lock.json +11741 -11741
- package/src/ruvocal/package.json +121 -121
- package/src/ruvocal/postcss.config.js +6 -6
- package/src/ruvocal/rvf.manifest.json +204 -204
- package/src/ruvocal/scripts/config.ts +64 -64
- package/src/ruvocal/scripts/generate-welcome.mjs +181 -181
- package/src/ruvocal/scripts/populate.ts +288 -288
- package/src/ruvocal/scripts/samples.txt +194 -194
- package/src/ruvocal/scripts/setups/vitest-setup-server.ts +44 -44
- package/src/ruvocal/scripts/updateLocalEnv.ts +48 -48
- package/src/ruvocal/src/ambient.d.ts +7 -7
- package/src/ruvocal/src/app.d.ts +29 -29
- package/src/ruvocal/src/app.html +53 -53
- package/src/ruvocal/src/hooks.server.ts +32 -32
- package/src/ruvocal/src/hooks.ts +6 -6
- package/src/ruvocal/src/lib/APIClient.ts +148 -148
- package/src/ruvocal/src/lib/actions/clickOutside.ts +18 -18
- package/src/ruvocal/src/lib/actions/snapScrollToBottom.ts +346 -346
- package/src/ruvocal/src/lib/buildPrompt.ts +33 -33
- package/src/ruvocal/src/lib/components/AnnouncementBanner.svelte +20 -20
- package/src/ruvocal/src/lib/components/BackgroundGenerationPoller.svelte +168 -168
- package/src/ruvocal/src/lib/components/CodeBlock.svelte +73 -73
- package/src/ruvocal/src/lib/components/CopyToClipBoardBtn.svelte +92 -92
- package/src/ruvocal/src/lib/components/DeleteConversationModal.svelte +75 -75
- package/src/ruvocal/src/lib/components/EditConversationModal.svelte +100 -100
- package/src/ruvocal/src/lib/components/ExpandNavigation.svelte +22 -22
- package/src/ruvocal/src/lib/components/FoundationBackground.svelte +242 -242
- package/src/ruvocal/src/lib/components/HoverTooltip.svelte +44 -44
- package/src/ruvocal/src/lib/components/HtmlPreviewModal.svelte +143 -143
- package/src/ruvocal/src/lib/components/InfiniteScroll.svelte +50 -50
- package/src/ruvocal/src/lib/components/MobileNav.svelte +300 -300
- package/src/ruvocal/src/lib/components/Modal.svelte +115 -115
- package/src/ruvocal/src/lib/components/ModelCardMetadata.svelte +71 -71
- package/src/ruvocal/src/lib/components/NavConversationItem.svelte +151 -151
- package/src/ruvocal/src/lib/components/NavMenu.svelte +313 -313
- package/src/ruvocal/src/lib/components/Pagination.svelte +97 -97
- package/src/ruvocal/src/lib/components/PaginationArrow.svelte +27 -27
- package/src/ruvocal/src/lib/components/Portal.svelte +24 -24
- package/src/ruvocal/src/lib/components/RetryBtn.svelte +18 -18
- package/src/ruvocal/src/lib/components/RuFloUniverse.svelte +185 -185
- package/src/ruvocal/src/lib/components/RufloHelpModal.svelte +411 -411
- package/src/ruvocal/src/lib/components/ScrollToBottomBtn.svelte +47 -47
- package/src/ruvocal/src/lib/components/ScrollToPreviousBtn.svelte +77 -77
- package/src/ruvocal/src/lib/components/ShareConversationModal.svelte +182 -182
- package/src/ruvocal/src/lib/components/StopGeneratingBtn.svelte +69 -69
- package/src/ruvocal/src/lib/components/SubscribeModal.svelte +87 -87
- package/src/ruvocal/src/lib/components/Switch.svelte +36 -36
- package/src/ruvocal/src/lib/components/SystemPromptModal.svelte +44 -44
- package/src/ruvocal/src/lib/components/Toast.svelte +27 -27
- package/src/ruvocal/src/lib/components/Tooltip.svelte +30 -30
- package/src/ruvocal/src/lib/components/WelcomeModal.svelte +46 -46
- package/src/ruvocal/src/lib/components/chat/Alternatives.svelte +77 -77
- package/src/ruvocal/src/lib/components/chat/BlockWrapper.svelte +72 -72
- package/src/ruvocal/src/lib/components/chat/ChatInput.svelte +490 -490
- package/src/ruvocal/src/lib/components/chat/ChatIntroduction.svelte +123 -123
- package/src/ruvocal/src/lib/components/chat/ChatMessage.svelte +548 -548
- package/src/ruvocal/src/lib/components/chat/ChatWindow.svelte +1057 -1057
- package/src/ruvocal/src/lib/components/chat/FileDropzone.svelte +92 -92
- package/src/ruvocal/src/lib/components/chat/ImageLightbox.svelte +66 -66
- package/src/ruvocal/src/lib/components/chat/MarkdownBlock.svelte +23 -23
- package/src/ruvocal/src/lib/components/chat/MarkdownRenderer.svelte +69 -69
- package/src/ruvocal/src/lib/components/chat/MarkdownRenderer.svelte.test.ts +58 -58
- package/src/ruvocal/src/lib/components/chat/MessageAvatar.svelte +103 -103
- package/src/ruvocal/src/lib/components/chat/ModelSwitch.svelte +64 -64
- package/src/ruvocal/src/lib/components/chat/OpenReasoningResults.svelte +81 -81
- package/src/ruvocal/src/lib/components/chat/TaskGroup.svelte +88 -88
- package/src/ruvocal/src/lib/components/chat/ToolUpdate.svelte +273 -273
- package/src/ruvocal/src/lib/components/chat/UploadedFile.svelte +253 -253
- package/src/ruvocal/src/lib/components/chat/UrlFetchModal.svelte +203 -203
- package/src/ruvocal/src/lib/components/chat/VoiceRecorder.svelte +214 -214
- package/src/ruvocal/src/lib/components/icons/IconBurger.svelte +20 -20
- package/src/ruvocal/src/lib/components/icons/IconCheap.svelte +20 -20
- package/src/ruvocal/src/lib/components/icons/IconChevron.svelte +24 -24
- package/src/ruvocal/src/lib/components/icons/IconDazzled.svelte +40 -40
- package/src/ruvocal/src/lib/components/icons/IconFast.svelte +20 -20
- package/src/ruvocal/src/lib/components/icons/IconLoading.svelte +22 -22
- package/src/ruvocal/src/lib/components/icons/IconMCP.svelte +28 -28
- package/src/ruvocal/src/lib/components/icons/IconMoon.svelte +21 -21
- package/src/ruvocal/src/lib/components/icons/IconNew.svelte +20 -20
- package/src/ruvocal/src/lib/components/icons/IconOmni.svelte +90 -90
- package/src/ruvocal/src/lib/components/icons/IconPaperclip.svelte +24 -24
- package/src/ruvocal/src/lib/components/icons/IconPro.svelte +37 -37
- package/src/ruvocal/src/lib/components/icons/IconShare.svelte +21 -21
- package/src/ruvocal/src/lib/components/icons/IconSun.svelte +93 -93
- package/src/ruvocal/src/lib/components/icons/Logo.svelte +68 -68
- package/src/ruvocal/src/lib/components/icons/LogoHuggingFaceBorderless.svelte +54 -54
- package/src/ruvocal/src/lib/components/mcp/AddServerForm.svelte +250 -250
- package/src/ruvocal/src/lib/components/mcp/MCPServerManager.svelte +185 -185
- package/src/ruvocal/src/lib/components/mcp/ServerCard.svelte +203 -203
- package/src/ruvocal/src/lib/components/players/AudioPlayer.svelte +82 -82
- package/src/ruvocal/src/lib/components/voice/AudioWaveform.svelte +96 -96
- package/src/ruvocal/src/lib/components/wasm/GalleryPanel.svelte +357 -357
- package/src/ruvocal/src/lib/constants/mcpExamples.ts +114 -114
- package/src/ruvocal/src/lib/constants/mime.ts +11 -11
- package/src/ruvocal/src/lib/constants/pagination.ts +1 -1
- package/src/ruvocal/src/lib/constants/publicSepToken.ts +1 -1
- package/src/ruvocal/src/lib/constants/routerExamples.ts +133 -133
- package/src/ruvocal/src/lib/constants/rvagentPresets.ts +206 -206
- package/src/ruvocal/src/lib/createShareLink.ts +27 -27
- package/src/ruvocal/src/lib/jobs/refresh-conversation-stats.ts +297 -297
- package/src/ruvocal/src/lib/migrations/lock.ts +56 -56
- package/src/ruvocal/src/lib/migrations/migrations.spec.ts +74 -74
- package/src/ruvocal/src/lib/migrations/migrations.ts +109 -109
- package/src/ruvocal/src/lib/migrations/routines/01-update-search-assistants.ts +50 -50
- package/src/ruvocal/src/lib/migrations/routines/02-update-assistants-models.ts +48 -48
- package/src/ruvocal/src/lib/migrations/routines/04-update-message-updates.ts +151 -151
- package/src/ruvocal/src/lib/migrations/routines/05-update-message-files.ts +56 -56
- package/src/ruvocal/src/lib/migrations/routines/06-trim-message-updates.ts +56 -56
- package/src/ruvocal/src/lib/migrations/routines/08-update-featured-to-review.ts +32 -32
- package/src/ruvocal/src/lib/migrations/routines/09-delete-empty-conversations.spec.ts +214 -214
- package/src/ruvocal/src/lib/migrations/routines/09-delete-empty-conversations.ts +88 -88
- package/src/ruvocal/src/lib/migrations/routines/10-update-reports-assistantid.ts +29 -29
- package/src/ruvocal/src/lib/migrations/routines/index.ts +15 -15
- package/src/ruvocal/src/lib/server/__tests__/conversation-stop-generating.spec.ts +103 -103
- package/src/ruvocal/src/lib/server/abortRegistry.ts +57 -57
- package/src/ruvocal/src/lib/server/abortedGenerations.ts +43 -43
- package/src/ruvocal/src/lib/server/adminToken.ts +62 -62
- package/src/ruvocal/src/lib/server/api/__tests__/conversations-id.spec.ts +296 -296
- package/src/ruvocal/src/lib/server/api/__tests__/conversations-message.spec.ts +216 -216
- package/src/ruvocal/src/lib/server/api/__tests__/conversations.spec.ts +235 -235
- package/src/ruvocal/src/lib/server/api/__tests__/misc.spec.ts +72 -72
- package/src/ruvocal/src/lib/server/api/__tests__/testHelpers.ts +86 -86
- package/src/ruvocal/src/lib/server/api/__tests__/user-reports.spec.ts +78 -78
- package/src/ruvocal/src/lib/server/api/__tests__/user.spec.ts +239 -239
- package/src/ruvocal/src/lib/server/api/types.ts +37 -37
- package/src/ruvocal/src/lib/server/api/utils/requireAuth.ts +22 -22
- package/src/ruvocal/src/lib/server/api/utils/resolveConversation.ts +69 -69
- package/src/ruvocal/src/lib/server/api/utils/resolveModel.ts +27 -27
- package/src/ruvocal/src/lib/server/api/utils/superjsonResponse.ts +15 -15
- package/src/ruvocal/src/lib/server/apiToken.ts +11 -11
- package/src/ruvocal/src/lib/server/auth.ts +554 -554
- package/src/ruvocal/src/lib/server/config.ts +187 -187
- package/src/ruvocal/src/lib/server/conversation.ts +83 -83
- package/src/ruvocal/src/lib/server/database/__tests__/rvf.spec.ts +709 -709
- package/src/ruvocal/src/lib/server/database/postgres.ts +700 -700
- package/src/ruvocal/src/lib/server/database/rvf.ts +1078 -1078
- package/src/ruvocal/src/lib/server/database.ts +145 -145
- package/src/ruvocal/src/lib/server/endpoints/document.ts +68 -68
- package/src/ruvocal/src/lib/server/endpoints/endpoints.ts +43 -43
- package/src/ruvocal/src/lib/server/endpoints/images.ts +211 -211
- package/src/ruvocal/src/lib/server/endpoints/openai/endpointOai.ts +266 -266
- package/src/ruvocal/src/lib/server/endpoints/openai/openAIChatToTextGenerationStream.ts +212 -212
- package/src/ruvocal/src/lib/server/endpoints/openai/openAICompletionToTextGenerationStream.ts +32 -32
- package/src/ruvocal/src/lib/server/endpoints/preprocessMessages.ts +61 -61
- package/src/ruvocal/src/lib/server/exitHandler.ts +59 -59
- package/src/ruvocal/src/lib/server/files/downloadFile.ts +34 -34
- package/src/ruvocal/src/lib/server/files/uploadFile.ts +29 -29
- package/src/ruvocal/src/lib/server/findRepoRoot.ts +13 -13
- package/src/ruvocal/src/lib/server/generateFromDefaultEndpoint.ts +46 -46
- package/src/ruvocal/src/lib/server/hooks/error.ts +37 -37
- package/src/ruvocal/src/lib/server/hooks/fetch.ts +22 -22
- package/src/ruvocal/src/lib/server/hooks/handle.ts +250 -250
- package/src/ruvocal/src/lib/server/hooks/init.ts +51 -51
- package/src/ruvocal/src/lib/server/isURLLocal.spec.ts +31 -31
- package/src/ruvocal/src/lib/server/isURLLocal.ts +74 -74
- package/src/ruvocal/src/lib/server/logger.ts +42 -42
- package/src/ruvocal/src/lib/server/mcp/clientPool.spec.ts +175 -175
- package/src/ruvocal/src/lib/server/mcp/hf.ts +32 -32
- package/src/ruvocal/src/lib/server/mcp/httpClient.ts +122 -122
- package/src/ruvocal/src/lib/server/mcp/registry.ts +76 -76
- package/src/ruvocal/src/lib/server/mcp/tools.ts +196 -196
- package/src/ruvocal/src/lib/server/metrics.ts +255 -255
- package/src/ruvocal/src/lib/server/models.ts +518 -518
- package/src/ruvocal/src/lib/server/requestContext.ts +55 -55
- package/src/ruvocal/src/lib/server/router/arch.ts +230 -230
- package/src/ruvocal/src/lib/server/router/endpoint.ts +316 -316
- package/src/ruvocal/src/lib/server/router/multimodal.ts +28 -28
- package/src/ruvocal/src/lib/server/router/policy.ts +49 -49
- package/src/ruvocal/src/lib/server/router/toolsRoute.ts +51 -51
- package/src/ruvocal/src/lib/server/router/types.ts +21 -21
- package/src/ruvocal/src/lib/server/sendSlack.ts +23 -23
- package/src/ruvocal/src/lib/server/textGeneration/generate.ts +258 -258
- package/src/ruvocal/src/lib/server/textGeneration/index.ts +96 -96
- package/src/ruvocal/src/lib/server/textGeneration/mcp/fileRefs.ts +155 -155
- package/src/ruvocal/src/lib/server/textGeneration/mcp/routerResolution.ts +108 -108
- package/src/ruvocal/src/lib/server/textGeneration/mcp/runMcpFlow.ts +831 -831
- package/src/ruvocal/src/lib/server/textGeneration/mcp/toolInvocation.ts +349 -349
- package/src/ruvocal/src/lib/server/textGeneration/mcp/wasmTools.test.ts +633 -633
- package/src/ruvocal/src/lib/server/textGeneration/reasoning.ts +23 -23
- package/src/ruvocal/src/lib/server/textGeneration/title.ts +83 -83
- package/src/ruvocal/src/lib/server/textGeneration/types.ts +28 -28
- package/src/ruvocal/src/lib/server/textGeneration/utils/prepareFiles.ts +88 -88
- package/src/ruvocal/src/lib/server/textGeneration/utils/routing.ts +21 -21
- package/src/ruvocal/src/lib/server/textGeneration/utils/toolPrompt.ts +49 -49
- package/src/ruvocal/src/lib/server/urlSafety.ts +77 -77
- package/src/ruvocal/src/lib/server/usageLimits.ts +30 -30
- package/src/ruvocal/src/lib/stores/autopilotStore.svelte.ts +175 -175
- package/src/ruvocal/src/lib/stores/backgroundGenerations.svelte.ts +32 -32
- package/src/ruvocal/src/lib/stores/backgroundGenerations.ts +1 -1
- package/src/ruvocal/src/lib/stores/errors.ts +9 -9
- package/src/ruvocal/src/lib/stores/isAborted.ts +3 -3
- package/src/ruvocal/src/lib/stores/isPro.ts +4 -4
- package/src/ruvocal/src/lib/stores/loading.ts +3 -3
- package/src/ruvocal/src/lib/stores/mcpServers.ts +534 -534
- package/src/ruvocal/src/lib/stores/pendingChatInput.ts +3 -3
- package/src/ruvocal/src/lib/stores/pendingMessage.ts +9 -9
- package/src/ruvocal/src/lib/stores/settings.ts +182 -182
- package/src/ruvocal/src/lib/stores/shareModal.ts +13 -13
- package/src/ruvocal/src/lib/stores/titleUpdate.ts +8 -8
- package/src/ruvocal/src/lib/stores/wasmMcp.ts +472 -472
- package/src/ruvocal/src/lib/switchTheme.ts +124 -124
- package/src/ruvocal/src/lib/types/AbortedGeneration.ts +8 -8
- package/src/ruvocal/src/lib/types/Assistant.ts +31 -31
- package/src/ruvocal/src/lib/types/AssistantStats.ts +11 -11
- package/src/ruvocal/src/lib/types/ConfigKey.ts +4 -4
- package/src/ruvocal/src/lib/types/ConvSidebar.ts +9 -9
- package/src/ruvocal/src/lib/types/Conversation.ts +27 -27
- package/src/ruvocal/src/lib/types/ConversationStats.ts +13 -13
- package/src/ruvocal/src/lib/types/Message.ts +41 -41
- package/src/ruvocal/src/lib/types/MessageEvent.ts +10 -10
- package/src/ruvocal/src/lib/types/MessageUpdate.ts +139 -139
- package/src/ruvocal/src/lib/types/MigrationResult.ts +7 -7
- package/src/ruvocal/src/lib/types/Model.ts +23 -23
- package/src/ruvocal/src/lib/types/Report.ts +12 -12
- package/src/ruvocal/src/lib/types/Review.ts +6 -6
- package/src/ruvocal/src/lib/types/Semaphore.ts +19 -19
- package/src/ruvocal/src/lib/types/Session.ts +22 -22
- package/src/ruvocal/src/lib/types/Settings.ts +93 -93
- package/src/ruvocal/src/lib/types/SharedConversation.ts +9 -9
- package/src/ruvocal/src/lib/types/Template.ts +6 -6
- package/src/ruvocal/src/lib/types/Timestamps.ts +4 -4
- package/src/ruvocal/src/lib/types/TokenCache.ts +6 -6
- package/src/ruvocal/src/lib/types/Tool.ts +77 -77
- package/src/ruvocal/src/lib/types/UrlDependency.ts +5 -5
- package/src/ruvocal/src/lib/types/User.ts +14 -14
- package/src/ruvocal/src/lib/utils/PublicConfig.svelte.ts +75 -75
- package/src/ruvocal/src/lib/utils/auth.ts +17 -17
- package/src/ruvocal/src/lib/utils/chunk.ts +33 -33
- package/src/ruvocal/src/lib/utils/cookiesAreEnabled.ts +13 -13
- package/src/ruvocal/src/lib/utils/debounce.ts +17 -17
- package/src/ruvocal/src/lib/utils/deepestChild.ts +6 -6
- package/src/ruvocal/src/lib/utils/favicon.ts +21 -21
- package/src/ruvocal/src/lib/utils/fetchJSON.ts +23 -23
- package/src/ruvocal/src/lib/utils/file2base64.ts +14 -14
- package/src/ruvocal/src/lib/utils/formatUserCount.ts +37 -37
- package/src/ruvocal/src/lib/utils/generationState.spec.ts +75 -75
- package/src/ruvocal/src/lib/utils/generationState.ts +26 -26
- package/src/ruvocal/src/lib/utils/getHref.ts +41 -41
- package/src/ruvocal/src/lib/utils/getReturnFromGenerator.ts +7 -7
- package/src/ruvocal/src/lib/utils/haptics.ts +64 -64
- package/src/ruvocal/src/lib/utils/hashConv.ts +12 -12
- package/src/ruvocal/src/lib/utils/hf.ts +17 -17
- package/src/ruvocal/src/lib/utils/isDesktop.ts +7 -7
- package/src/ruvocal/src/lib/utils/isUrl.ts +8 -8
- package/src/ruvocal/src/lib/utils/isVirtualKeyboard.ts +16 -16
- package/src/ruvocal/src/lib/utils/loadAttachmentsFromUrls.ts +115 -115
- package/src/ruvocal/src/lib/utils/marked.spec.ts +96 -96
- package/src/ruvocal/src/lib/utils/marked.ts +531 -531
- package/src/ruvocal/src/lib/utils/mcpValidation.ts +147 -147
- package/src/ruvocal/src/lib/utils/mergeAsyncGenerators.ts +38 -38
- package/src/ruvocal/src/lib/utils/messageUpdates.spec.ts +262 -262
- package/src/ruvocal/src/lib/utils/messageUpdates.ts +324 -324
- package/src/ruvocal/src/lib/utils/mime.ts +56 -56
- package/src/ruvocal/src/lib/utils/models.ts +14 -14
- package/src/ruvocal/src/lib/utils/parseBlocks.ts +120 -120
- package/src/ruvocal/src/lib/utils/parseIncompleteMarkdown.ts +644 -644
- package/src/ruvocal/src/lib/utils/parseStringToList.ts +10 -10
- package/src/ruvocal/src/lib/utils/randomUuid.ts +14 -14
- package/src/ruvocal/src/lib/utils/searchTokens.ts +33 -33
- package/src/ruvocal/src/lib/utils/sha256.ts +7 -7
- package/src/ruvocal/src/lib/utils/stringifyError.ts +12 -12
- package/src/ruvocal/src/lib/utils/sum.ts +3 -3
- package/src/ruvocal/src/lib/utils/template.spec.ts +59 -59
- package/src/ruvocal/src/lib/utils/template.ts +53 -53
- package/src/ruvocal/src/lib/utils/timeout.ts +9 -9
- package/src/ruvocal/src/lib/utils/toolProgress.spec.ts +46 -46
- package/src/ruvocal/src/lib/utils/toolProgress.ts +11 -11
- package/src/ruvocal/src/lib/utils/tree/addChildren.spec.ts +102 -102
- package/src/ruvocal/src/lib/utils/tree/addChildren.ts +48 -48
- package/src/ruvocal/src/lib/utils/tree/addSibling.spec.ts +81 -81
- package/src/ruvocal/src/lib/utils/tree/addSibling.ts +41 -41
- package/src/ruvocal/src/lib/utils/tree/buildSubtree.spec.ts +110 -110
- package/src/ruvocal/src/lib/utils/tree/buildSubtree.ts +24 -24
- package/src/ruvocal/src/lib/utils/tree/convertLegacyConversation.spec.ts +31 -31
- package/src/ruvocal/src/lib/utils/tree/convertLegacyConversation.ts +36 -36
- package/src/ruvocal/src/lib/utils/tree/isMessageId.spec.ts +15 -15
- package/src/ruvocal/src/lib/utils/tree/isMessageId.ts +5 -5
- package/src/ruvocal/src/lib/utils/tree/tree.d.ts +14 -14
- package/src/ruvocal/src/lib/utils/tree/treeHelpers.spec.ts +167 -167
- package/src/ruvocal/src/lib/utils/updates.ts +39 -39
- package/src/ruvocal/src/lib/utils/urlParams.ts +13 -13
- package/src/ruvocal/src/lib/wasm/idb.ts +438 -438
- package/src/ruvocal/src/lib/wasm/index.ts +1213 -1213
- package/src/ruvocal/src/lib/wasm/tests/wasm-capabilities.test.ts +565 -565
- package/src/ruvocal/src/lib/wasm/wasm.worker.ts +332 -332
- package/src/ruvocal/src/lib/wasm/workerClient.ts +166 -166
- package/src/ruvocal/src/lib/workers/autopilotWorker.ts +221 -221
- package/src/ruvocal/src/lib/workers/detailFetchWorker.ts +100 -100
- package/src/ruvocal/src/lib/workers/markdownWorker.ts +61 -61
- package/src/ruvocal/src/routes/+error.svelte +20 -20
- package/src/ruvocal/src/routes/+layout.svelte +324 -324
- package/src/ruvocal/src/routes/+layout.ts +91 -91
- package/src/ruvocal/src/routes/+page.svelte +168 -168
- package/src/ruvocal/src/routes/.well-known/oauth-cimd/+server.ts +37 -37
- package/src/ruvocal/src/routes/__debug/openai/+server.ts +21 -21
- package/src/ruvocal/src/routes/admin/export/+server.ts +159 -159
- package/src/ruvocal/src/routes/admin/stats/compute/+server.ts +16 -16
- package/src/ruvocal/src/routes/api/conversation/[id]/+server.ts +40 -40
- package/src/ruvocal/src/routes/api/conversation/[id]/message/[messageId]/+server.ts +42 -42
- package/src/ruvocal/src/routes/api/conversations/+server.ts +48 -48
- package/src/ruvocal/src/routes/api/fetch-url/+server.ts +147 -147
- package/src/ruvocal/src/routes/api/mcp/health/+server.ts +292 -292
- package/src/ruvocal/src/routes/api/mcp/servers/+server.ts +32 -32
- package/src/ruvocal/src/routes/api/models/+server.ts +25 -25
- package/src/ruvocal/src/routes/api/transcribe/+server.ts +104 -104
- package/src/ruvocal/src/routes/api/user/+server.ts +15 -15
- package/src/ruvocal/src/routes/api/user/validate-token/+server.ts +20 -20
- package/src/ruvocal/src/routes/api/v2/conversations/+server.ts +48 -48
- package/src/ruvocal/src/routes/api/v2/conversations/[id]/+server.ts +94 -94
- package/src/ruvocal/src/routes/api/v2/conversations/[id]/message/[messageId]/+server.ts +43 -43
- package/src/ruvocal/src/routes/api/v2/conversations/import-share/+server.ts +23 -23
- package/src/ruvocal/src/routes/api/v2/debug/config/+server.ts +16 -16
- package/src/ruvocal/src/routes/api/v2/debug/refresh/+server.ts +30 -30
- package/src/ruvocal/src/routes/api/v2/export/+server.ts +196 -196
- package/src/ruvocal/src/routes/api/v2/feature-flags/+server.ts +14 -14
- package/src/ruvocal/src/routes/api/v2/models/+server.ts +38 -38
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/+server.ts +8 -8
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/[model]/+server.ts +8 -8
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/[model]/subscribe/+server.ts +28 -28
- package/src/ruvocal/src/routes/api/v2/models/[namespace]/subscribe/+server.ts +28 -28
- package/src/ruvocal/src/routes/api/v2/models/old/+server.ts +7 -7
- package/src/ruvocal/src/routes/api/v2/models/refresh/+server.ts +33 -33
- package/src/ruvocal/src/routes/api/v2/public-config/+server.ts +7 -7
- package/src/ruvocal/src/routes/api/v2/user/+server.ts +17 -17
- package/src/ruvocal/src/routes/api/v2/user/billing-orgs/+server.ts +73 -73
- package/src/ruvocal/src/routes/api/v2/user/reports/+server.ts +17 -17
- package/src/ruvocal/src/routes/api/v2/user/settings/+server.ts +110 -110
- package/src/ruvocal/src/routes/conversation/+server.ts +115 -115
- package/src/ruvocal/src/routes/conversation/[id]/+page.svelte +586 -586
- package/src/ruvocal/src/routes/conversation/[id]/+page.ts +60 -60
- package/src/ruvocal/src/routes/conversation/[id]/+server.ts +740 -740
- package/src/ruvocal/src/routes/conversation/[id]/message/[messageId]/prompt/+server.ts +66 -66
- package/src/ruvocal/src/routes/conversation/[id]/share/+server.ts +69 -69
- package/src/ruvocal/src/routes/conversation/[id]/stop-generating/+server.ts +35 -35
- package/src/ruvocal/src/routes/healthcheck/+server.ts +3 -3
- package/src/ruvocal/src/routes/login/+server.ts +5 -5
- package/src/ruvocal/src/routes/login/callback/+server.ts +103 -103
- package/src/ruvocal/src/routes/login/callback/updateUser.spec.ts +157 -157
- package/src/ruvocal/src/routes/login/callback/updateUser.ts +215 -215
- package/src/ruvocal/src/routes/logout/+server.ts +18 -18
- package/src/ruvocal/src/routes/metrics/+server.ts +18 -18
- package/src/ruvocal/src/routes/models/+page.svelte +233 -233
- package/src/ruvocal/src/routes/models/[...model]/+page.svelte +161 -161
- package/src/ruvocal/src/routes/models/[...model]/+page.ts +14 -14
- package/src/ruvocal/src/routes/models/[...model]/thumbnail.png/+server.ts +64 -64
- package/src/ruvocal/src/routes/models/[...model]/thumbnail.png/ModelThumbnail.svelte +28 -28
- package/src/ruvocal/src/routes/privacy/+page.svelte +11 -11
- package/src/ruvocal/src/routes/r/[id]/+page.ts +34 -34
- package/src/ruvocal/src/routes/settings/(nav)/+layout.svelte +282 -282
- package/src/ruvocal/src/routes/settings/(nav)/+layout.ts +1 -1
- package/src/ruvocal/src/routes/settings/(nav)/+server.ts +59 -59
- package/src/ruvocal/src/routes/settings/(nav)/[...model]/+page.svelte +464 -464
- package/src/ruvocal/src/routes/settings/(nav)/[...model]/+page.ts +14 -14
- package/src/ruvocal/src/routes/settings/(nav)/application/+page.svelte +362 -362
- package/src/ruvocal/src/routes/settings/+layout.svelte +40 -40
- package/src/ruvocal/src/styles/highlight-js.css +195 -195
- package/src/ruvocal/src/styles/main.css +144 -144
- package/src/ruvocal/static/chatui/favicon-dark.svg +3 -3
- package/src/ruvocal/static/chatui/favicon-dev.svg +3 -3
- package/src/ruvocal/static/chatui/favicon.svg +3 -3
- package/src/ruvocal/static/chatui/icon.svg +3 -3
- package/src/ruvocal/static/chatui/logo.svg +7 -7
- package/src/ruvocal/static/chatui/manifest.json +54 -54
- package/src/ruvocal/static/chatui/welcome.js +184 -184
- package/src/ruvocal/static/huggingchat/favicon-dark.svg +4 -4
- package/src/ruvocal/static/huggingchat/favicon-dev.svg +4 -4
- package/src/ruvocal/static/huggingchat/favicon.svg +4 -4
- package/src/ruvocal/static/huggingchat/fulltext-logo.svg +1 -1
- package/src/ruvocal/static/huggingchat/icon.svg +4 -4
- package/src/ruvocal/static/huggingchat/logo.svg +4 -4
- package/src/ruvocal/static/huggingchat/manifest.json +54 -54
- package/src/ruvocal/static/huggingchat/routes.chat.json +226 -226
- package/src/ruvocal/static/robots.txt +10 -10
- package/src/ruvocal/static/wasm/rvagent_wasm.js +1539 -1539
- package/src/ruvocal/stub/@reflink/reflink/package.json +5 -5
- package/src/ruvocal/svelte.config.js +53 -53
- package/src/ruvocal/tailwind.config.cjs +30 -30
- package/src/ruvocal/tsconfig.json +19 -19
- package/src/ruvocal/vite.config.ts +87 -87
- package/src/scripts/deploy.sh +116 -116
- package/src/scripts/generate-config.js +245 -245
- package/src/scripts/generate-welcome.js +187 -187
- package/src/scripts/package-rvf.sh +116 -116
|
@@ -1,464 +1,464 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { page } from "$app/state";
|
|
3
|
-
import { base } from "$app/paths";
|
|
4
|
-
|
|
5
|
-
import type { BackendModel } from "$lib/server/models";
|
|
6
|
-
import IconOmni from "$lib/components/icons/IconOmni.svelte";
|
|
7
|
-
import IconFast from "$lib/components/icons/IconFast.svelte";
|
|
8
|
-
import IconCheap from "$lib/components/icons/IconCheap.svelte";
|
|
9
|
-
import { useSettingsStore } from "$lib/stores/settings";
|
|
10
|
-
import CopyToClipBoardBtn from "$lib/components/CopyToClipBoardBtn.svelte";
|
|
11
|
-
import CarbonArrowUpRight from "~icons/carbon/arrow-up-right";
|
|
12
|
-
import CarbonCopy from "~icons/carbon/copy";
|
|
13
|
-
import CarbonChat from "~icons/carbon/chat";
|
|
14
|
-
import CarbonCode from "~icons/carbon/code";
|
|
15
|
-
import CarbonChevronDown from "~icons/carbon/chevron-down";
|
|
16
|
-
import LucideCheck from "~icons/lucide/check";
|
|
17
|
-
import CarbonMagicWandFilled from "~icons/carbon/magic-wand-filled";
|
|
18
|
-
import { PROVIDERS_HUB_ORGS } from "@huggingface/inference";
|
|
19
|
-
import { Select } from "bits-ui";
|
|
20
|
-
|
|
21
|
-
import { goto } from "$app/navigation";
|
|
22
|
-
import { usePublicConfig } from "$lib/utils/PublicConfig.svelte";
|
|
23
|
-
import Switch from "$lib/components/Switch.svelte";
|
|
24
|
-
|
|
25
|
-
const publicConfig = usePublicConfig();
|
|
26
|
-
const settings = useSettingsStore();
|
|
27
|
-
const modelId = $derived(page.params.model ?? "");
|
|
28
|
-
|
|
29
|
-
// Functional bindings for nested settings (Svelte 5):
|
|
30
|
-
// Avoid binding directly to $settings.*[modelId]; write via store update
|
|
31
|
-
function getToolsOverride() {
|
|
32
|
-
return (
|
|
33
|
-
$settings.toolsOverrides?.[modelId] ??
|
|
34
|
-
Boolean((model as unknown as { supportsTools?: boolean }).supportsTools)
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
function setToolsOverride(v: boolean) {
|
|
38
|
-
settings.update((s) => ({
|
|
39
|
-
...s,
|
|
40
|
-
toolsOverrides: { ...s.toolsOverrides, [modelId]: v },
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
43
|
-
function getMultimodalOverride() {
|
|
44
|
-
return $settings.multimodalOverrides?.[modelId] ?? Boolean(model?.multimodal);
|
|
45
|
-
}
|
|
46
|
-
function setMultimodalOverride(v: boolean) {
|
|
47
|
-
settings.update((s) => ({
|
|
48
|
-
...s,
|
|
49
|
-
multimodalOverrides: { ...s.multimodalOverrides, [modelId]: v },
|
|
50
|
-
}));
|
|
51
|
-
}
|
|
52
|
-
function getHidePromptExamples() {
|
|
53
|
-
return $settings.hidePromptExamples?.[modelId] ?? false;
|
|
54
|
-
}
|
|
55
|
-
function setHidePromptExamples(v: boolean) {
|
|
56
|
-
settings.update((s) => ({
|
|
57
|
-
...s,
|
|
58
|
-
hidePromptExamples: { ...s.hidePromptExamples, [modelId]: v },
|
|
59
|
-
}));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function getProviderOverride() {
|
|
63
|
-
return $settings.providerOverrides?.[modelId] ?? "auto";
|
|
64
|
-
}
|
|
65
|
-
function setProviderOverride(v: string) {
|
|
66
|
-
settings.update((s) => ({
|
|
67
|
-
...s,
|
|
68
|
-
providerOverrides: { ...s.providerOverrides, [modelId]: v },
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function getCustomPrompt() {
|
|
73
|
-
return $settings.customPrompts?.[modelId] ?? "";
|
|
74
|
-
}
|
|
75
|
-
function setCustomPrompt(v: string) {
|
|
76
|
-
settings.update((s) => ({
|
|
77
|
-
...s,
|
|
78
|
-
customPrompts: { ...s.customPrompts, [modelId]: v },
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
type RouterProvider = { provider: string } & Record<string, unknown>;
|
|
83
|
-
|
|
84
|
-
$effect(() => {
|
|
85
|
-
const defaultPreprompt =
|
|
86
|
-
page.data.models.find((el: BackendModel) => el.id === modelId)?.preprompt || "";
|
|
87
|
-
settings.initValue("customPrompts", modelId, defaultPreprompt);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
let hasCustomPreprompt = $derived(
|
|
91
|
-
$settings.customPrompts[modelId] !==
|
|
92
|
-
page.data.models.find((el: BackendModel) => el.id === modelId)?.preprompt
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
let model = $derived(page.data.models.find((el: BackendModel) => el.id === modelId));
|
|
96
|
-
let providerList: RouterProvider[] = $derived((model?.providers ?? []) as RouterProvider[]);
|
|
97
|
-
|
|
98
|
-
// Initialize multimodal override for this model if not set yet
|
|
99
|
-
$effect(() => {
|
|
100
|
-
if (model) {
|
|
101
|
-
// Default to the model's advertised capability
|
|
102
|
-
settings.initValue("multimodalOverrides", modelId, !!model.multimodal);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Initialize tools override for this model if not set yet
|
|
107
|
-
$effect(() => {
|
|
108
|
-
if (model) {
|
|
109
|
-
settings.initValue(
|
|
110
|
-
"toolsOverrides",
|
|
111
|
-
modelId,
|
|
112
|
-
Boolean((model as unknown as { supportsTools?: boolean }).supportsTools)
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Ensure hidePromptExamples has an entry for this model so the switch can bind safely
|
|
118
|
-
$effect(() => {
|
|
119
|
-
settings.initValue("hidePromptExamples", modelId, false);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Initialize provider override for this model (default to "auto")
|
|
123
|
-
$effect(() => {
|
|
124
|
-
settings.initValue("providerOverrides", modelId, "auto");
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// Provider selection policies for the dropdown
|
|
128
|
-
const PROVIDER_POLICIES = [
|
|
129
|
-
{ value: "auto", label: "Auto (your HF preference order)" },
|
|
130
|
-
{ value: "fastest", label: "Fastest (highest throughput)" },
|
|
131
|
-
{ value: "cheapest", label: "Cheapest (lowest cost)" },
|
|
132
|
-
] as const;
|
|
133
|
-
</script>
|
|
134
|
-
|
|
135
|
-
<div class="flex flex-col items-start">
|
|
136
|
-
<div class="mb-4 flex flex-col gap-0.5">
|
|
137
|
-
<h2 class="text-base font-semibold md:text-lg">
|
|
138
|
-
{model.displayName}
|
|
139
|
-
</h2>
|
|
140
|
-
|
|
141
|
-
{#if model.description}
|
|
142
|
-
<p class="line-clamp-2 whitespace-pre-wrap text-sm text-gray-600 dark:text-gray-400">
|
|
143
|
-
{model.description}
|
|
144
|
-
</p>
|
|
145
|
-
{/if}
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<!-- Actions -->
|
|
149
|
-
<div class="mb-4 flex flex-wrap items-center gap-1.5">
|
|
150
|
-
<button
|
|
151
|
-
class="flex w-fit items-center rounded-full bg-black px-3 py-1.5 text-sm !text-white shadow-sm hover:bg-black/90 dark:bg-white/80 dark:!text-gray-900 dark:hover:bg-white/90"
|
|
152
|
-
name="Activate model"
|
|
153
|
-
onclick={(e) => {
|
|
154
|
-
e.stopPropagation();
|
|
155
|
-
settings.instantSet({
|
|
156
|
-
activeModel: modelId,
|
|
157
|
-
});
|
|
158
|
-
goto(`${base}/`);
|
|
159
|
-
}}
|
|
160
|
-
>
|
|
161
|
-
<CarbonChat class="mr-1.5 text-sm" />
|
|
162
|
-
New chat
|
|
163
|
-
</button>
|
|
164
|
-
|
|
165
|
-
{#if model.modelUrl}
|
|
166
|
-
<a
|
|
167
|
-
href={model.modelUrl || "https://huggingface.co/" + model.name}
|
|
168
|
-
target="_blank"
|
|
169
|
-
rel="noreferrer"
|
|
170
|
-
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
171
|
-
>
|
|
172
|
-
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
173
|
-
Model page
|
|
174
|
-
</a>
|
|
175
|
-
{/if}
|
|
176
|
-
|
|
177
|
-
{#if model.datasetName || model.datasetUrl}
|
|
178
|
-
<a
|
|
179
|
-
href={model.datasetUrl || "https://huggingface.co/datasets/" + model.datasetName}
|
|
180
|
-
target="_blank"
|
|
181
|
-
rel="noreferrer"
|
|
182
|
-
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
183
|
-
>
|
|
184
|
-
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
185
|
-
Dataset page
|
|
186
|
-
</a>
|
|
187
|
-
{/if}
|
|
188
|
-
|
|
189
|
-
{#if model.websiteUrl}
|
|
190
|
-
<a
|
|
191
|
-
href={model.websiteUrl}
|
|
192
|
-
target="_blank"
|
|
193
|
-
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
194
|
-
rel="noreferrer"
|
|
195
|
-
>
|
|
196
|
-
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
197
|
-
Model website
|
|
198
|
-
</a>
|
|
199
|
-
{/if}
|
|
200
|
-
|
|
201
|
-
{#if publicConfig.isHuggingChat}
|
|
202
|
-
{#if !model?.isRouter}
|
|
203
|
-
<a
|
|
204
|
-
href={"https://huggingface.co/" + model.name + "?inference_api=true"}
|
|
205
|
-
target="_blank"
|
|
206
|
-
rel="noreferrer"
|
|
207
|
-
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
208
|
-
>
|
|
209
|
-
<CarbonCode class="mr-1.5 shrink-0 text-xs" />
|
|
210
|
-
Use via API
|
|
211
|
-
</a>
|
|
212
|
-
<a
|
|
213
|
-
href={"https://huggingface.co/" + model.name}
|
|
214
|
-
target="_blank"
|
|
215
|
-
rel="noreferrer"
|
|
216
|
-
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
217
|
-
>
|
|
218
|
-
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs" />
|
|
219
|
-
View model card
|
|
220
|
-
</a>
|
|
221
|
-
{/if}
|
|
222
|
-
<CopyToClipBoardBtn
|
|
223
|
-
value="{publicConfig.PUBLIC_ORIGIN || page.url.origin}{base}/models/{model.id}"
|
|
224
|
-
classNames="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
225
|
-
>
|
|
226
|
-
<div class="flex items-center gap-1.5">
|
|
227
|
-
<CarbonCopy class="shrink-0 text-xs" />Copy direct link
|
|
228
|
-
</div>
|
|
229
|
-
</CopyToClipBoardBtn>
|
|
230
|
-
{/if}
|
|
231
|
-
</div>
|
|
232
|
-
|
|
233
|
-
<div class="relative flex w-full flex-col gap-2">
|
|
234
|
-
{#if model?.isRouter}
|
|
235
|
-
<p class="mb-3 mt-2 rounded-lg bg-gray-100 px-3 py-2 text-sm dark:bg-white/5">
|
|
236
|
-
<IconOmni classNames="-translate-y-px" /> Omni routes your messages to the best underlying model
|
|
237
|
-
depending on your request.
|
|
238
|
-
</p>
|
|
239
|
-
{/if}
|
|
240
|
-
<div class="flex w-full flex-row content-between">
|
|
241
|
-
<h3 class="mb-1 text-[15px] font-semibold text-gray-800 dark:text-gray-200">System Prompt</h3>
|
|
242
|
-
{#if hasCustomPreprompt}
|
|
243
|
-
<button
|
|
244
|
-
class="ml-auto text-xs underline decoration-gray-300 hover:decoration-gray-700 dark:decoration-gray-700 dark:hover:decoration-gray-400"
|
|
245
|
-
onclick={(e) => {
|
|
246
|
-
e.stopPropagation();
|
|
247
|
-
settings.update((s) => ({
|
|
248
|
-
...s,
|
|
249
|
-
customPrompts: { ...s.customPrompts, [modelId]: model.preprompt },
|
|
250
|
-
}));
|
|
251
|
-
}}
|
|
252
|
-
>
|
|
253
|
-
Reset
|
|
254
|
-
</button>
|
|
255
|
-
{/if}
|
|
256
|
-
</div>
|
|
257
|
-
|
|
258
|
-
<textarea
|
|
259
|
-
aria-label="Custom system prompt"
|
|
260
|
-
rows="8"
|
|
261
|
-
class="w-full resize-none rounded-md border border-gray-200 bg-gray-50 p-2 text-[13px] dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200"
|
|
262
|
-
bind:value={getCustomPrompt, setCustomPrompt}
|
|
263
|
-
></textarea>
|
|
264
|
-
<!-- Capabilities -->
|
|
265
|
-
<div
|
|
266
|
-
class="mt-3 rounded-xl border border-gray-200 bg-white px-3 shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
|
267
|
-
>
|
|
268
|
-
<div class="divide-y divide-gray-200 dark:divide-gray-700">
|
|
269
|
-
<div class="flex items-start justify-between py-3">
|
|
270
|
-
<div>
|
|
271
|
-
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
272
|
-
Tool calling (functions)
|
|
273
|
-
</div>
|
|
274
|
-
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
275
|
-
Enable tools and allow the model to call them in chat.
|
|
276
|
-
</p>
|
|
277
|
-
</div>
|
|
278
|
-
<Switch name="forceTools" bind:checked={getToolsOverride, setToolsOverride} />
|
|
279
|
-
</div>
|
|
280
|
-
|
|
281
|
-
<div class="flex items-start justify-between py-3">
|
|
282
|
-
<div>
|
|
283
|
-
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
284
|
-
Multimodal support (image inputs)
|
|
285
|
-
</div>
|
|
286
|
-
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
287
|
-
Enable image uploads and send images to this model.
|
|
288
|
-
</p>
|
|
289
|
-
</div>
|
|
290
|
-
<Switch
|
|
291
|
-
name="forceMultimodal"
|
|
292
|
-
bind:checked={getMultimodalOverride, setMultimodalOverride}
|
|
293
|
-
/>
|
|
294
|
-
</div>
|
|
295
|
-
|
|
296
|
-
{#if model?.isRouter}
|
|
297
|
-
<div class="flex items-start justify-between py-3">
|
|
298
|
-
<div>
|
|
299
|
-
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
300
|
-
Hide prompt examples
|
|
301
|
-
</div>
|
|
302
|
-
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
303
|
-
Hide the prompt suggestions above the chat input.
|
|
304
|
-
</p>
|
|
305
|
-
</div>
|
|
306
|
-
<Switch
|
|
307
|
-
name="hidePromptExamples"
|
|
308
|
-
bind:checked={getHidePromptExamples, setHidePromptExamples}
|
|
309
|
-
/>
|
|
310
|
-
</div>
|
|
311
|
-
{/if}
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
|
-
{#if publicConfig.isHuggingChat && model.providers?.length && !model?.isRouter}
|
|
316
|
-
<div
|
|
317
|
-
class="mt-3 flex flex-col items-start gap-2.5 rounded-xl border border-gray-200 bg-white px-3 py-3 shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
|
318
|
-
>
|
|
319
|
-
<div>
|
|
320
|
-
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
321
|
-
Inference Providers
|
|
322
|
-
</div>
|
|
323
|
-
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
324
|
-
Choose which Inference Provider to use with this model. You can also manage provider
|
|
325
|
-
preferences in <a
|
|
326
|
-
class="underline decoration-gray-400 hover:decoration-gray-700 dark:decoration-gray-500 dark:hover:decoration-gray-300"
|
|
327
|
-
target="_blank"
|
|
328
|
-
href="https://huggingface.co/settings/inference-providers/settings"
|
|
329
|
-
>your HF settings</a
|
|
330
|
-
>.
|
|
331
|
-
</p>
|
|
332
|
-
</div>
|
|
333
|
-
<Select.Root
|
|
334
|
-
type="single"
|
|
335
|
-
value={getProviderOverride()}
|
|
336
|
-
onValueChange={(v) => v && setProviderOverride(v)}
|
|
337
|
-
>
|
|
338
|
-
<Select.Trigger
|
|
339
|
-
aria-label="Select inference provider"
|
|
340
|
-
class="inline-flex w-auto items-center justify-between gap-2 rounded-lg border border-gray-200 bg-white px-2 py-2 text-sm text-gray-800 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-800"
|
|
341
|
-
>
|
|
342
|
-
{@const currentValue = getProviderOverride()}
|
|
343
|
-
{@const currentPolicy = PROVIDER_POLICIES.find((p) => p.value === currentValue)}
|
|
344
|
-
{@const currentProvider = providerList.find((p) => p.provider === currentValue)}
|
|
345
|
-
<span class="flex items-center gap-2">
|
|
346
|
-
{#if currentValue === "auto"}
|
|
347
|
-
<span class="grid size-5 flex-none place-items-center rounded-md bg-gray-500/10">
|
|
348
|
-
<CarbonMagicWandFilled class="size-3 text-gray-700 dark:text-gray-300" />
|
|
349
|
-
</span>
|
|
350
|
-
{:else if currentValue === "fastest"}
|
|
351
|
-
<span
|
|
352
|
-
class="grid size-5 flex-none place-items-center rounded-md bg-green-500/10 text-green-600 dark:text-green-500"
|
|
353
|
-
>
|
|
354
|
-
<IconFast classNames="size-3" />
|
|
355
|
-
</span>
|
|
356
|
-
{:else if currentValue === "cheapest"}
|
|
357
|
-
<span
|
|
358
|
-
class="grid size-5 flex-none place-items-center rounded-md bg-blue-500/10 text-blue-600 dark:text-blue-500"
|
|
359
|
-
>
|
|
360
|
-
<IconCheap classNames="size-3" />
|
|
361
|
-
</span>
|
|
362
|
-
{:else if currentProvider}
|
|
363
|
-
{@const hubOrg =
|
|
364
|
-
PROVIDERS_HUB_ORGS[currentValue as keyof typeof PROVIDERS_HUB_ORGS]}
|
|
365
|
-
{#if hubOrg}
|
|
366
|
-
<span
|
|
367
|
-
class="flex size-5 flex-none items-center justify-center rounded-md bg-gray-500/10 p-0.5"
|
|
368
|
-
>
|
|
369
|
-
<img
|
|
370
|
-
src="https://huggingface.co/api/avatars/{hubOrg}"
|
|
371
|
-
alt=""
|
|
372
|
-
class="size-full rounded"
|
|
373
|
-
/>
|
|
374
|
-
</span>
|
|
375
|
-
{/if}
|
|
376
|
-
{/if}
|
|
377
|
-
{currentPolicy?.label ?? currentProvider?.provider ?? currentValue}
|
|
378
|
-
</span>
|
|
379
|
-
<CarbonChevronDown class="size-4 text-gray-500" />
|
|
380
|
-
</Select.Trigger>
|
|
381
|
-
<Select.Portal>
|
|
382
|
-
<Select.Content
|
|
383
|
-
class="scrollbar-custom z-50 max-h-60 overflow-y-auto rounded-xl border border-gray-200 bg-white/95 p-1 shadow-lg backdrop-blur dark:border-gray-700 dark:bg-gray-800/95"
|
|
384
|
-
sideOffset={4}
|
|
385
|
-
>
|
|
386
|
-
<Select.Group>
|
|
387
|
-
<Select.GroupHeading
|
|
388
|
-
class="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
389
|
-
>
|
|
390
|
-
Selection mode
|
|
391
|
-
</Select.GroupHeading>
|
|
392
|
-
{#each PROVIDER_POLICIES as opt (opt.value)}
|
|
393
|
-
<Select.Item
|
|
394
|
-
value={opt.value}
|
|
395
|
-
class="flex cursor-pointer select-none items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-gray-700 outline-none data-[highlighted]:bg-gray-100 dark:text-gray-200 dark:data-[highlighted]:bg-white/10"
|
|
396
|
-
>
|
|
397
|
-
{#if opt.value === "auto"}
|
|
398
|
-
<span
|
|
399
|
-
class="grid size-5 flex-none place-items-center rounded-md bg-gray-500/10"
|
|
400
|
-
>
|
|
401
|
-
<CarbonMagicWandFilled class="size-3 text-gray-700 dark:text-gray-300" />
|
|
402
|
-
</span>
|
|
403
|
-
{:else if opt.value === "fastest"}
|
|
404
|
-
<span
|
|
405
|
-
class="grid size-5 flex-none place-items-center rounded-md bg-green-500/10 text-green-600 dark:text-green-500"
|
|
406
|
-
>
|
|
407
|
-
<IconFast classNames="size-3" />
|
|
408
|
-
</span>
|
|
409
|
-
{:else if opt.value === "cheapest"}
|
|
410
|
-
<span
|
|
411
|
-
class="grid size-5 flex-none place-items-center rounded-md bg-blue-500/10 text-blue-600 dark:text-blue-500"
|
|
412
|
-
>
|
|
413
|
-
<IconCheap classNames="size-3" />
|
|
414
|
-
</span>
|
|
415
|
-
{/if}
|
|
416
|
-
<span class="flex-1">{opt.label}</span>
|
|
417
|
-
{#if getProviderOverride() === opt.value}
|
|
418
|
-
<LucideCheck class="size-4 text-gray-500" />
|
|
419
|
-
{/if}
|
|
420
|
-
</Select.Item>
|
|
421
|
-
{/each}
|
|
422
|
-
</Select.Group>
|
|
423
|
-
<div class="my-1 h-px bg-gray-200 dark:bg-gray-700"></div>
|
|
424
|
-
<Select.Group>
|
|
425
|
-
<Select.GroupHeading
|
|
426
|
-
class="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
427
|
-
>
|
|
428
|
-
Specific provider
|
|
429
|
-
</Select.GroupHeading>
|
|
430
|
-
{#each providerList as prov (prov.provider)}
|
|
431
|
-
{@const hubOrg =
|
|
432
|
-
PROVIDERS_HUB_ORGS[prov.provider as keyof typeof PROVIDERS_HUB_ORGS]}
|
|
433
|
-
<Select.Item
|
|
434
|
-
value={prov.provider}
|
|
435
|
-
class="flex cursor-pointer select-none items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-gray-700 outline-none data-[highlighted]:bg-gray-100 dark:text-gray-200 dark:data-[highlighted]:bg-white/10"
|
|
436
|
-
>
|
|
437
|
-
{#if hubOrg}
|
|
438
|
-
<span
|
|
439
|
-
class="flex size-5 flex-none items-center justify-center rounded-md bg-gray-500/10 p-0.5"
|
|
440
|
-
>
|
|
441
|
-
<img
|
|
442
|
-
src="https://huggingface.co/api/avatars/{hubOrg}"
|
|
443
|
-
alt=""
|
|
444
|
-
class="size-full rounded"
|
|
445
|
-
/>
|
|
446
|
-
</span>
|
|
447
|
-
{:else}
|
|
448
|
-
<span class="size-5"></span>
|
|
449
|
-
{/if}
|
|
450
|
-
<span class="flex-1">{prov.provider}</span>
|
|
451
|
-
{#if getProviderOverride() === prov.provider}
|
|
452
|
-
<LucideCheck class="size-4 text-gray-500" />
|
|
453
|
-
{/if}
|
|
454
|
-
</Select.Item>
|
|
455
|
-
{/each}
|
|
456
|
-
</Select.Group>
|
|
457
|
-
</Select.Content>
|
|
458
|
-
</Select.Portal>
|
|
459
|
-
</Select.Root>
|
|
460
|
-
</div>
|
|
461
|
-
{/if}
|
|
462
|
-
<!-- Tokenizer-based token counting disabled in this build -->
|
|
463
|
-
</div>
|
|
464
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { page } from "$app/state";
|
|
3
|
+
import { base } from "$app/paths";
|
|
4
|
+
|
|
5
|
+
import type { BackendModel } from "$lib/server/models";
|
|
6
|
+
import IconOmni from "$lib/components/icons/IconOmni.svelte";
|
|
7
|
+
import IconFast from "$lib/components/icons/IconFast.svelte";
|
|
8
|
+
import IconCheap from "$lib/components/icons/IconCheap.svelte";
|
|
9
|
+
import { useSettingsStore } from "$lib/stores/settings";
|
|
10
|
+
import CopyToClipBoardBtn from "$lib/components/CopyToClipBoardBtn.svelte";
|
|
11
|
+
import CarbonArrowUpRight from "~icons/carbon/arrow-up-right";
|
|
12
|
+
import CarbonCopy from "~icons/carbon/copy";
|
|
13
|
+
import CarbonChat from "~icons/carbon/chat";
|
|
14
|
+
import CarbonCode from "~icons/carbon/code";
|
|
15
|
+
import CarbonChevronDown from "~icons/carbon/chevron-down";
|
|
16
|
+
import LucideCheck from "~icons/lucide/check";
|
|
17
|
+
import CarbonMagicWandFilled from "~icons/carbon/magic-wand-filled";
|
|
18
|
+
import { PROVIDERS_HUB_ORGS } from "@huggingface/inference";
|
|
19
|
+
import { Select } from "bits-ui";
|
|
20
|
+
|
|
21
|
+
import { goto } from "$app/navigation";
|
|
22
|
+
import { usePublicConfig } from "$lib/utils/PublicConfig.svelte";
|
|
23
|
+
import Switch from "$lib/components/Switch.svelte";
|
|
24
|
+
|
|
25
|
+
const publicConfig = usePublicConfig();
|
|
26
|
+
const settings = useSettingsStore();
|
|
27
|
+
const modelId = $derived(page.params.model ?? "");
|
|
28
|
+
|
|
29
|
+
// Functional bindings for nested settings (Svelte 5):
|
|
30
|
+
// Avoid binding directly to $settings.*[modelId]; write via store update
|
|
31
|
+
function getToolsOverride() {
|
|
32
|
+
return (
|
|
33
|
+
$settings.toolsOverrides?.[modelId] ??
|
|
34
|
+
Boolean((model as unknown as { supportsTools?: boolean }).supportsTools)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function setToolsOverride(v: boolean) {
|
|
38
|
+
settings.update((s) => ({
|
|
39
|
+
...s,
|
|
40
|
+
toolsOverrides: { ...s.toolsOverrides, [modelId]: v },
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
function getMultimodalOverride() {
|
|
44
|
+
return $settings.multimodalOverrides?.[modelId] ?? Boolean(model?.multimodal);
|
|
45
|
+
}
|
|
46
|
+
function setMultimodalOverride(v: boolean) {
|
|
47
|
+
settings.update((s) => ({
|
|
48
|
+
...s,
|
|
49
|
+
multimodalOverrides: { ...s.multimodalOverrides, [modelId]: v },
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
function getHidePromptExamples() {
|
|
53
|
+
return $settings.hidePromptExamples?.[modelId] ?? false;
|
|
54
|
+
}
|
|
55
|
+
function setHidePromptExamples(v: boolean) {
|
|
56
|
+
settings.update((s) => ({
|
|
57
|
+
...s,
|
|
58
|
+
hidePromptExamples: { ...s.hidePromptExamples, [modelId]: v },
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getProviderOverride() {
|
|
63
|
+
return $settings.providerOverrides?.[modelId] ?? "auto";
|
|
64
|
+
}
|
|
65
|
+
function setProviderOverride(v: string) {
|
|
66
|
+
settings.update((s) => ({
|
|
67
|
+
...s,
|
|
68
|
+
providerOverrides: { ...s.providerOverrides, [modelId]: v },
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getCustomPrompt() {
|
|
73
|
+
return $settings.customPrompts?.[modelId] ?? "";
|
|
74
|
+
}
|
|
75
|
+
function setCustomPrompt(v: string) {
|
|
76
|
+
settings.update((s) => ({
|
|
77
|
+
...s,
|
|
78
|
+
customPrompts: { ...s.customPrompts, [modelId]: v },
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type RouterProvider = { provider: string } & Record<string, unknown>;
|
|
83
|
+
|
|
84
|
+
$effect(() => {
|
|
85
|
+
const defaultPreprompt =
|
|
86
|
+
page.data.models.find((el: BackendModel) => el.id === modelId)?.preprompt || "";
|
|
87
|
+
settings.initValue("customPrompts", modelId, defaultPreprompt);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
let hasCustomPreprompt = $derived(
|
|
91
|
+
$settings.customPrompts[modelId] !==
|
|
92
|
+
page.data.models.find((el: BackendModel) => el.id === modelId)?.preprompt
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
let model = $derived(page.data.models.find((el: BackendModel) => el.id === modelId));
|
|
96
|
+
let providerList: RouterProvider[] = $derived((model?.providers ?? []) as RouterProvider[]);
|
|
97
|
+
|
|
98
|
+
// Initialize multimodal override for this model if not set yet
|
|
99
|
+
$effect(() => {
|
|
100
|
+
if (model) {
|
|
101
|
+
// Default to the model's advertised capability
|
|
102
|
+
settings.initValue("multimodalOverrides", modelId, !!model.multimodal);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Initialize tools override for this model if not set yet
|
|
107
|
+
$effect(() => {
|
|
108
|
+
if (model) {
|
|
109
|
+
settings.initValue(
|
|
110
|
+
"toolsOverrides",
|
|
111
|
+
modelId,
|
|
112
|
+
Boolean((model as unknown as { supportsTools?: boolean }).supportsTools)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Ensure hidePromptExamples has an entry for this model so the switch can bind safely
|
|
118
|
+
$effect(() => {
|
|
119
|
+
settings.initValue("hidePromptExamples", modelId, false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Initialize provider override for this model (default to "auto")
|
|
123
|
+
$effect(() => {
|
|
124
|
+
settings.initValue("providerOverrides", modelId, "auto");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Provider selection policies for the dropdown
|
|
128
|
+
const PROVIDER_POLICIES = [
|
|
129
|
+
{ value: "auto", label: "Auto (your HF preference order)" },
|
|
130
|
+
{ value: "fastest", label: "Fastest (highest throughput)" },
|
|
131
|
+
{ value: "cheapest", label: "Cheapest (lowest cost)" },
|
|
132
|
+
] as const;
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<div class="flex flex-col items-start">
|
|
136
|
+
<div class="mb-4 flex flex-col gap-0.5">
|
|
137
|
+
<h2 class="text-base font-semibold md:text-lg">
|
|
138
|
+
{model.displayName}
|
|
139
|
+
</h2>
|
|
140
|
+
|
|
141
|
+
{#if model.description}
|
|
142
|
+
<p class="line-clamp-2 whitespace-pre-wrap text-sm text-gray-600 dark:text-gray-400">
|
|
143
|
+
{model.description}
|
|
144
|
+
</p>
|
|
145
|
+
{/if}
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<!-- Actions -->
|
|
149
|
+
<div class="mb-4 flex flex-wrap items-center gap-1.5">
|
|
150
|
+
<button
|
|
151
|
+
class="flex w-fit items-center rounded-full bg-black px-3 py-1.5 text-sm !text-white shadow-sm hover:bg-black/90 dark:bg-white/80 dark:!text-gray-900 dark:hover:bg-white/90"
|
|
152
|
+
name="Activate model"
|
|
153
|
+
onclick={(e) => {
|
|
154
|
+
e.stopPropagation();
|
|
155
|
+
settings.instantSet({
|
|
156
|
+
activeModel: modelId,
|
|
157
|
+
});
|
|
158
|
+
goto(`${base}/`);
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
<CarbonChat class="mr-1.5 text-sm" />
|
|
162
|
+
New chat
|
|
163
|
+
</button>
|
|
164
|
+
|
|
165
|
+
{#if model.modelUrl}
|
|
166
|
+
<a
|
|
167
|
+
href={model.modelUrl || "https://huggingface.co/" + model.name}
|
|
168
|
+
target="_blank"
|
|
169
|
+
rel="noreferrer"
|
|
170
|
+
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
171
|
+
>
|
|
172
|
+
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
173
|
+
Model page
|
|
174
|
+
</a>
|
|
175
|
+
{/if}
|
|
176
|
+
|
|
177
|
+
{#if model.datasetName || model.datasetUrl}
|
|
178
|
+
<a
|
|
179
|
+
href={model.datasetUrl || "https://huggingface.co/datasets/" + model.datasetName}
|
|
180
|
+
target="_blank"
|
|
181
|
+
rel="noreferrer"
|
|
182
|
+
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
183
|
+
>
|
|
184
|
+
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
185
|
+
Dataset page
|
|
186
|
+
</a>
|
|
187
|
+
{/if}
|
|
188
|
+
|
|
189
|
+
{#if model.websiteUrl}
|
|
190
|
+
<a
|
|
191
|
+
href={model.websiteUrl}
|
|
192
|
+
target="_blank"
|
|
193
|
+
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
194
|
+
rel="noreferrer"
|
|
195
|
+
>
|
|
196
|
+
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
|
|
197
|
+
Model website
|
|
198
|
+
</a>
|
|
199
|
+
{/if}
|
|
200
|
+
|
|
201
|
+
{#if publicConfig.isHuggingChat}
|
|
202
|
+
{#if !model?.isRouter}
|
|
203
|
+
<a
|
|
204
|
+
href={"https://huggingface.co/" + model.name + "?inference_api=true"}
|
|
205
|
+
target="_blank"
|
|
206
|
+
rel="noreferrer"
|
|
207
|
+
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
208
|
+
>
|
|
209
|
+
<CarbonCode class="mr-1.5 shrink-0 text-xs" />
|
|
210
|
+
Use via API
|
|
211
|
+
</a>
|
|
212
|
+
<a
|
|
213
|
+
href={"https://huggingface.co/" + model.name}
|
|
214
|
+
target="_blank"
|
|
215
|
+
rel="noreferrer"
|
|
216
|
+
class="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
217
|
+
>
|
|
218
|
+
<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs" />
|
|
219
|
+
View model card
|
|
220
|
+
</a>
|
|
221
|
+
{/if}
|
|
222
|
+
<CopyToClipBoardBtn
|
|
223
|
+
value="{publicConfig.PUBLIC_ORIGIN || page.url.origin}{base}/models/{model.id}"
|
|
224
|
+
classNames="inline-flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700/60"
|
|
225
|
+
>
|
|
226
|
+
<div class="flex items-center gap-1.5">
|
|
227
|
+
<CarbonCopy class="shrink-0 text-xs" />Copy direct link
|
|
228
|
+
</div>
|
|
229
|
+
</CopyToClipBoardBtn>
|
|
230
|
+
{/if}
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="relative flex w-full flex-col gap-2">
|
|
234
|
+
{#if model?.isRouter}
|
|
235
|
+
<p class="mb-3 mt-2 rounded-lg bg-gray-100 px-3 py-2 text-sm dark:bg-white/5">
|
|
236
|
+
<IconOmni classNames="-translate-y-px" /> Omni routes your messages to the best underlying model
|
|
237
|
+
depending on your request.
|
|
238
|
+
</p>
|
|
239
|
+
{/if}
|
|
240
|
+
<div class="flex w-full flex-row content-between">
|
|
241
|
+
<h3 class="mb-1 text-[15px] font-semibold text-gray-800 dark:text-gray-200">System Prompt</h3>
|
|
242
|
+
{#if hasCustomPreprompt}
|
|
243
|
+
<button
|
|
244
|
+
class="ml-auto text-xs underline decoration-gray-300 hover:decoration-gray-700 dark:decoration-gray-700 dark:hover:decoration-gray-400"
|
|
245
|
+
onclick={(e) => {
|
|
246
|
+
e.stopPropagation();
|
|
247
|
+
settings.update((s) => ({
|
|
248
|
+
...s,
|
|
249
|
+
customPrompts: { ...s.customPrompts, [modelId]: model.preprompt },
|
|
250
|
+
}));
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
Reset
|
|
254
|
+
</button>
|
|
255
|
+
{/if}
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<textarea
|
|
259
|
+
aria-label="Custom system prompt"
|
|
260
|
+
rows="8"
|
|
261
|
+
class="w-full resize-none rounded-md border border-gray-200 bg-gray-50 p-2 text-[13px] dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200"
|
|
262
|
+
bind:value={getCustomPrompt, setCustomPrompt}
|
|
263
|
+
></textarea>
|
|
264
|
+
<!-- Capabilities -->
|
|
265
|
+
<div
|
|
266
|
+
class="mt-3 rounded-xl border border-gray-200 bg-white px-3 shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
|
267
|
+
>
|
|
268
|
+
<div class="divide-y divide-gray-200 dark:divide-gray-700">
|
|
269
|
+
<div class="flex items-start justify-between py-3">
|
|
270
|
+
<div>
|
|
271
|
+
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
272
|
+
Tool calling (functions)
|
|
273
|
+
</div>
|
|
274
|
+
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
275
|
+
Enable tools and allow the model to call them in chat.
|
|
276
|
+
</p>
|
|
277
|
+
</div>
|
|
278
|
+
<Switch name="forceTools" bind:checked={getToolsOverride, setToolsOverride} />
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
<div class="flex items-start justify-between py-3">
|
|
282
|
+
<div>
|
|
283
|
+
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
284
|
+
Multimodal support (image inputs)
|
|
285
|
+
</div>
|
|
286
|
+
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
287
|
+
Enable image uploads and send images to this model.
|
|
288
|
+
</p>
|
|
289
|
+
</div>
|
|
290
|
+
<Switch
|
|
291
|
+
name="forceMultimodal"
|
|
292
|
+
bind:checked={getMultimodalOverride, setMultimodalOverride}
|
|
293
|
+
/>
|
|
294
|
+
</div>
|
|
295
|
+
|
|
296
|
+
{#if model?.isRouter}
|
|
297
|
+
<div class="flex items-start justify-between py-3">
|
|
298
|
+
<div>
|
|
299
|
+
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
300
|
+
Hide prompt examples
|
|
301
|
+
</div>
|
|
302
|
+
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
303
|
+
Hide the prompt suggestions above the chat input.
|
|
304
|
+
</p>
|
|
305
|
+
</div>
|
|
306
|
+
<Switch
|
|
307
|
+
name="hidePromptExamples"
|
|
308
|
+
bind:checked={getHidePromptExamples, setHidePromptExamples}
|
|
309
|
+
/>
|
|
310
|
+
</div>
|
|
311
|
+
{/if}
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
{#if publicConfig.isHuggingChat && model.providers?.length && !model?.isRouter}
|
|
316
|
+
<div
|
|
317
|
+
class="mt-3 flex flex-col items-start gap-2.5 rounded-xl border border-gray-200 bg-white px-3 py-3 shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
|
318
|
+
>
|
|
319
|
+
<div>
|
|
320
|
+
<div class="text-[13px] font-medium text-gray-800 dark:text-gray-200">
|
|
321
|
+
Inference Providers
|
|
322
|
+
</div>
|
|
323
|
+
<p class="text-[12px] text-gray-500 dark:text-gray-400">
|
|
324
|
+
Choose which Inference Provider to use with this model. You can also manage provider
|
|
325
|
+
preferences in <a
|
|
326
|
+
class="underline decoration-gray-400 hover:decoration-gray-700 dark:decoration-gray-500 dark:hover:decoration-gray-300"
|
|
327
|
+
target="_blank"
|
|
328
|
+
href="https://huggingface.co/settings/inference-providers/settings"
|
|
329
|
+
>your HF settings</a
|
|
330
|
+
>.
|
|
331
|
+
</p>
|
|
332
|
+
</div>
|
|
333
|
+
<Select.Root
|
|
334
|
+
type="single"
|
|
335
|
+
value={getProviderOverride()}
|
|
336
|
+
onValueChange={(v) => v && setProviderOverride(v)}
|
|
337
|
+
>
|
|
338
|
+
<Select.Trigger
|
|
339
|
+
aria-label="Select inference provider"
|
|
340
|
+
class="inline-flex w-auto items-center justify-between gap-2 rounded-lg border border-gray-200 bg-white px-2 py-2 text-sm text-gray-800 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-200 dark:hover:bg-gray-800"
|
|
341
|
+
>
|
|
342
|
+
{@const currentValue = getProviderOverride()}
|
|
343
|
+
{@const currentPolicy = PROVIDER_POLICIES.find((p) => p.value === currentValue)}
|
|
344
|
+
{@const currentProvider = providerList.find((p) => p.provider === currentValue)}
|
|
345
|
+
<span class="flex items-center gap-2">
|
|
346
|
+
{#if currentValue === "auto"}
|
|
347
|
+
<span class="grid size-5 flex-none place-items-center rounded-md bg-gray-500/10">
|
|
348
|
+
<CarbonMagicWandFilled class="size-3 text-gray-700 dark:text-gray-300" />
|
|
349
|
+
</span>
|
|
350
|
+
{:else if currentValue === "fastest"}
|
|
351
|
+
<span
|
|
352
|
+
class="grid size-5 flex-none place-items-center rounded-md bg-green-500/10 text-green-600 dark:text-green-500"
|
|
353
|
+
>
|
|
354
|
+
<IconFast classNames="size-3" />
|
|
355
|
+
</span>
|
|
356
|
+
{:else if currentValue === "cheapest"}
|
|
357
|
+
<span
|
|
358
|
+
class="grid size-5 flex-none place-items-center rounded-md bg-blue-500/10 text-blue-600 dark:text-blue-500"
|
|
359
|
+
>
|
|
360
|
+
<IconCheap classNames="size-3" />
|
|
361
|
+
</span>
|
|
362
|
+
{:else if currentProvider}
|
|
363
|
+
{@const hubOrg =
|
|
364
|
+
PROVIDERS_HUB_ORGS[currentValue as keyof typeof PROVIDERS_HUB_ORGS]}
|
|
365
|
+
{#if hubOrg}
|
|
366
|
+
<span
|
|
367
|
+
class="flex size-5 flex-none items-center justify-center rounded-md bg-gray-500/10 p-0.5"
|
|
368
|
+
>
|
|
369
|
+
<img
|
|
370
|
+
src="https://huggingface.co/api/avatars/{hubOrg}"
|
|
371
|
+
alt=""
|
|
372
|
+
class="size-full rounded"
|
|
373
|
+
/>
|
|
374
|
+
</span>
|
|
375
|
+
{/if}
|
|
376
|
+
{/if}
|
|
377
|
+
{currentPolicy?.label ?? currentProvider?.provider ?? currentValue}
|
|
378
|
+
</span>
|
|
379
|
+
<CarbonChevronDown class="size-4 text-gray-500" />
|
|
380
|
+
</Select.Trigger>
|
|
381
|
+
<Select.Portal>
|
|
382
|
+
<Select.Content
|
|
383
|
+
class="scrollbar-custom z-50 max-h-60 overflow-y-auto rounded-xl border border-gray-200 bg-white/95 p-1 shadow-lg backdrop-blur dark:border-gray-700 dark:bg-gray-800/95"
|
|
384
|
+
sideOffset={4}
|
|
385
|
+
>
|
|
386
|
+
<Select.Group>
|
|
387
|
+
<Select.GroupHeading
|
|
388
|
+
class="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
389
|
+
>
|
|
390
|
+
Selection mode
|
|
391
|
+
</Select.GroupHeading>
|
|
392
|
+
{#each PROVIDER_POLICIES as opt (opt.value)}
|
|
393
|
+
<Select.Item
|
|
394
|
+
value={opt.value}
|
|
395
|
+
class="flex cursor-pointer select-none items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-gray-700 outline-none data-[highlighted]:bg-gray-100 dark:text-gray-200 dark:data-[highlighted]:bg-white/10"
|
|
396
|
+
>
|
|
397
|
+
{#if opt.value === "auto"}
|
|
398
|
+
<span
|
|
399
|
+
class="grid size-5 flex-none place-items-center rounded-md bg-gray-500/10"
|
|
400
|
+
>
|
|
401
|
+
<CarbonMagicWandFilled class="size-3 text-gray-700 dark:text-gray-300" />
|
|
402
|
+
</span>
|
|
403
|
+
{:else if opt.value === "fastest"}
|
|
404
|
+
<span
|
|
405
|
+
class="grid size-5 flex-none place-items-center rounded-md bg-green-500/10 text-green-600 dark:text-green-500"
|
|
406
|
+
>
|
|
407
|
+
<IconFast classNames="size-3" />
|
|
408
|
+
</span>
|
|
409
|
+
{:else if opt.value === "cheapest"}
|
|
410
|
+
<span
|
|
411
|
+
class="grid size-5 flex-none place-items-center rounded-md bg-blue-500/10 text-blue-600 dark:text-blue-500"
|
|
412
|
+
>
|
|
413
|
+
<IconCheap classNames="size-3" />
|
|
414
|
+
</span>
|
|
415
|
+
{/if}
|
|
416
|
+
<span class="flex-1">{opt.label}</span>
|
|
417
|
+
{#if getProviderOverride() === opt.value}
|
|
418
|
+
<LucideCheck class="size-4 text-gray-500" />
|
|
419
|
+
{/if}
|
|
420
|
+
</Select.Item>
|
|
421
|
+
{/each}
|
|
422
|
+
</Select.Group>
|
|
423
|
+
<div class="my-1 h-px bg-gray-200 dark:bg-gray-700"></div>
|
|
424
|
+
<Select.Group>
|
|
425
|
+
<Select.GroupHeading
|
|
426
|
+
class="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
427
|
+
>
|
|
428
|
+
Specific provider
|
|
429
|
+
</Select.GroupHeading>
|
|
430
|
+
{#each providerList as prov (prov.provider)}
|
|
431
|
+
{@const hubOrg =
|
|
432
|
+
PROVIDERS_HUB_ORGS[prov.provider as keyof typeof PROVIDERS_HUB_ORGS]}
|
|
433
|
+
<Select.Item
|
|
434
|
+
value={prov.provider}
|
|
435
|
+
class="flex cursor-pointer select-none items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-gray-700 outline-none data-[highlighted]:bg-gray-100 dark:text-gray-200 dark:data-[highlighted]:bg-white/10"
|
|
436
|
+
>
|
|
437
|
+
{#if hubOrg}
|
|
438
|
+
<span
|
|
439
|
+
class="flex size-5 flex-none items-center justify-center rounded-md bg-gray-500/10 p-0.5"
|
|
440
|
+
>
|
|
441
|
+
<img
|
|
442
|
+
src="https://huggingface.co/api/avatars/{hubOrg}"
|
|
443
|
+
alt=""
|
|
444
|
+
class="size-full rounded"
|
|
445
|
+
/>
|
|
446
|
+
</span>
|
|
447
|
+
{:else}
|
|
448
|
+
<span class="size-5"></span>
|
|
449
|
+
{/if}
|
|
450
|
+
<span class="flex-1">{prov.provider}</span>
|
|
451
|
+
{#if getProviderOverride() === prov.provider}
|
|
452
|
+
<LucideCheck class="size-4 text-gray-500" />
|
|
453
|
+
{/if}
|
|
454
|
+
</Select.Item>
|
|
455
|
+
{/each}
|
|
456
|
+
</Select.Group>
|
|
457
|
+
</Select.Content>
|
|
458
|
+
</Select.Portal>
|
|
459
|
+
</Select.Root>
|
|
460
|
+
</div>
|
|
461
|
+
{/if}
|
|
462
|
+
<!-- Tokenizer-based token counting disabled in this build -->
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|