diff --git a/pages/info/debug.tsx b/pages/info/debug.tsx index 7daefe7e4..0e4fb21b1 100644 --- a/pages/info/debug.tsx +++ b/pages/info/debug.tsx @@ -6,7 +6,7 @@ import DownloadIcon from '@mui/icons-material/Download'; import { AppPlaceholder } from '../../src/apps/AppPlaceholder'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { getPlantUmlServerUrl } from '~/modules/blocks/code/RenderCode'; import { withLayout } from '~/common/layout/withLayout'; @@ -76,7 +76,7 @@ function AppDebug() { const [saved, setSaved] = React.useState(false); // external state - const backendCapabilities = backendCaps(); + const backendCaps = backendCapabilities(); const chatsCount = useChatStore.getState().conversations?.length; const uxLabsExperiments = Object.entries(useUXLabsStore.getState()).filter(([_k, v]) => v === true).map(([k, _]) => k).join(', '); const { folders, enableFolders } = useFolderStore.getState(); @@ -112,7 +112,7 @@ function AppDebug() { }, }; const cBackend = { - configuration: backendCapabilities, + configuration: backendCaps, deployment: { home: Brand.URIs.Home, hostName: clientHostName(), diff --git a/src/modules/backend/store-backend-capabilities.ts b/src/modules/backend/store-backend-capabilities.ts index c8844be99..37e322bf0 100644 --- a/src/modules/backend/store-backend-capabilities.ts +++ b/src/modules/backend/store-backend-capabilities.ts @@ -68,6 +68,6 @@ export function useKnowledgeOfBackendCaps(): [boolean, (capabilities: Partial [state.loadedCapabilities, state.setCapabilities])); } -export function backendCaps(): BackendCapabilities { +export function backendCapabilities(): BackendCapabilities { return useBackendCapabilitiesStore.getState(); } diff --git a/src/modules/browse/store-module-browsing.tsx b/src/modules/browse/store-module-browsing.tsx index d102cf8b1..af07b799d 100644 --- a/src/modules/browse/store-module-browsing.tsx +++ b/src/modules/browse/store-module-browsing.tsx @@ -2,7 +2,7 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import { CapabilityBrowsing } from '~/common/components/useCapabilities'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; interface BrowseState { @@ -53,7 +53,7 @@ export const useBrowseStore = create()( export function useBrowseCapability(): CapabilityBrowsing { // server config - const isServerConfig = backendCaps().hasBrowsing; + const isServerConfig = backendCapabilities().hasBrowsing; // external client state const { wssEndpoint, enableCommandBrowse, enableComposerAttach, enableReactTool, enablePersonaTool } = useBrowseStore(); diff --git a/src/modules/elevenlabs/elevenlabs.client.ts b/src/modules/elevenlabs/elevenlabs.client.ts index 2707e1b84..590fb758f 100644 --- a/src/modules/elevenlabs/elevenlabs.client.ts +++ b/src/modules/elevenlabs/elevenlabs.client.ts @@ -1,4 +1,4 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { AudioLivePlayer } from '~/common/util/AudioLivePlayer'; import { CapabilityElevenLabsSpeechSynthesis } from '~/common/components/useCapabilities'; @@ -14,12 +14,12 @@ export const isValidElevenLabsApiKey = (apiKey?: string) => !!apiKey && apiKey.t export const isElevenLabsEnabled = (apiKey?: string) => apiKey ? isValidElevenLabsApiKey(apiKey) - : backendCaps().hasVoiceElevenLabs; + : backendCapabilities().hasVoiceElevenLabs; export function useCapability(): CapabilityElevenLabsSpeechSynthesis { const [clientApiKey, voiceId] = useElevenLabsData(); - const isConfiguredServerSide = backendCaps().hasVoiceElevenLabs; + const isConfiguredServerSide = backendCapabilities().hasVoiceElevenLabs; const isConfiguredClientSide = clientApiKey ? isValidElevenLabsApiKey(clientApiKey) : false; const mayWork = isConfiguredServerSide || isConfiguredClientSide || !!voiceId; return { mayWork, isConfiguredServerSide, isConfiguredClientSide }; diff --git a/src/modules/google/GoogleSearchSettings.tsx b/src/modules/google/GoogleSearchSettings.tsx index 88b9bdf63..4de30be66 100644 --- a/src/modules/google/GoogleSearchSettings.tsx +++ b/src/modules/google/GoogleSearchSettings.tsx @@ -5,7 +5,7 @@ import { FormControl, FormHelperText, Input } from '@mui/joy'; import KeyIcon from '@mui/icons-material/Key'; import SearchIcon from '@mui/icons-material/Search'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { FormLabelStart } from '~/common/components/forms/FormLabelStart'; import { Link } from '~/common/components/Link'; @@ -17,7 +17,7 @@ import { useGoogleSearchStore } from './store-module-google'; export function GoogleSearchSettings() { // external state - const backendHasGoogle = backendCaps().hasGoogleCustomSearch; + const backendHasGoogle = backendCapabilities().hasGoogleCustomSearch; const { googleCloudApiKey, setGoogleCloudApiKey, googleCSEId, setGoogleCSEId } = useGoogleSearchStore(state => ({ googleCloudApiKey: state.googleCloudApiKey, setGoogleCloudApiKey: state.setGoogleCloudApiKey, googleCSEId: state.googleCSEId, setGoogleCSEId: state.setGoogleCSEId, diff --git a/src/modules/llms/models-modal/ModelsSourceSelector.tsx b/src/modules/llms/models-modal/ModelsSourceSelector.tsx index 1ce515b5d..7dec28839 100644 --- a/src/modules/llms/models-modal/ModelsSourceSelector.tsx +++ b/src/modules/llms/models-modal/ModelsSourceSelector.tsx @@ -5,6 +5,8 @@ import { Badge, Box, Button, IconButton, ListItemDecorator, MenuItem, Option, Se import AddIcon from '@mui/icons-material/Add'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; + import { CloseableMenu } from '~/common/components/CloseableMenu'; import { ConfirmationModal } from '~/common/components/ConfirmationModal'; import { themeZIndexOverMobileDrawer } from '~/common/app.theme'; @@ -81,13 +83,14 @@ export function ModelsSourceSelector(props: { .map(vendor => { const sourceInstanceCount = modelSources.filter(source => source.vId === vendor.id).length; const enabled = vendor.instanceLimit > sourceInstanceCount; + const backendCaps = backendCapabilities(); return { vendor, enabled, component: ( handleAddSourceFromVendor(vendor.id)}> - {vendorIcon(vendor, !!vendor.hasBackendCap && vendor.hasBackendCap())} + {vendorIcon(vendor, !!vendor.hasBackendCap?.(backendCaps))} {vendor.name} diff --git a/src/modules/llms/vendors/IModelVendor.ts b/src/modules/llms/vendors/IModelVendor.ts index bcf383a52..d5b1503e6 100644 --- a/src/modules/llms/vendors/IModelVendor.ts +++ b/src/modules/llms/vendors/IModelVendor.ts @@ -3,6 +3,8 @@ import type { TRPCClientErrorBase } from '@trpc/client'; import type { SvgIconProps } from '@mui/joy'; +import type { BackendCapabilities } from '~/modules/backend/store-backend-capabilities'; + import type { DLLM, DLLMId, DModelSourceId } from '../store-llms'; import type { ModelDescriptionSchema } from '../server/llm.server.types'; import type { ModelVendorId } from './vendors.registry'; @@ -17,7 +19,7 @@ export interface IModelVendor boolean; // used to show a 'geen checkmark' in the list of vendors when adding sources + readonly hasBackendCap?: (backendCapabilities: BackendCapabilities) => boolean; // used to show a 'geen checkmark' in the list of vendors when adding sources // components readonly Icon: React.FunctionComponent; diff --git a/src/modules/llms/vendors/anthropic/AnthropicSourceSetup.tsx b/src/modules/llms/vendors/anthropic/AnthropicSourceSetup.tsx index 77de3726b..efb3e1d42 100644 --- a/src/modules/llms/vendors/anthropic/AnthropicSourceSetup.tsx +++ b/src/modules/llms/vendors/anthropic/AnthropicSourceSetup.tsx @@ -22,13 +22,12 @@ export function AnthropicSourceSetup(props: { sourceId: DModelSourceId }) { const advanced = useToggleableBoolean(); // external state - const { source, sourceHasLLMs, access, updateSetup } = + const { source, sourceHasLLMs, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorAnthropic); // derived state const { anthropicKey, anthropicHost, heliconeKey } = access; - const needsUserKey = !ModelVendorAnthropic.hasBackendCap?.(); const keyValid = isValidAnthropicApiKey(anthropicKey); const keyError = (/*needsUserKey ||*/ !!anthropicKey) && !keyValid; const shallFetchSucceed = anthropicKey ? keyValid : (!needsUserKey || !!anthropicHost); diff --git a/src/modules/llms/vendors/anthropic/anthropic.vendor.ts b/src/modules/llms/vendors/anthropic/anthropic.vendor.ts index 57f0825c2..aafb7dd92 100644 --- a/src/modules/llms/vendors/anthropic/anthropic.vendor.ts +++ b/src/modules/llms/vendors/anthropic/anthropic.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { AnthropicIcon } from '~/common/components/icons/vendors/AnthropicIcon'; import { apiAsync, apiQuery } from '~/common/util/trpc.client'; @@ -29,7 +27,7 @@ export const ModelVendorAnthropic: IModelVendor backendCaps().hasLlmAnthropic, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmAnthropic, // components Icon: AnthropicIcon, diff --git a/src/modules/llms/vendors/azure/AzureSourceSetup.tsx b/src/modules/llms/vendors/azure/AzureSourceSetup.tsx index 49c262dba..1fea97532 100644 --- a/src/modules/llms/vendors/azure/AzureSourceSetup.tsx +++ b/src/modules/llms/vendors/azure/AzureSourceSetup.tsx @@ -17,13 +17,12 @@ import { isValidAzureApiKey, ModelVendorAzure } from './azure.vendor'; export function AzureSourceSetup(props: { sourceId: DModelSourceId }) { // external state - const { source, sourceHasLLMs, access, updateSetup } = + const { source, sourceHasLLMs, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorAzure); // derived state const { oaiKey: azureKey, oaiHost: azureEndpoint } = access; - const needsUserKey = !ModelVendorAzure.hasBackendCap?.(); const keyValid = isValidAzureApiKey(azureKey); const keyError = (/*needsUserKey ||*/ !!azureKey) && !keyValid; const hostValid = !!asValidURL(azureEndpoint); diff --git a/src/modules/llms/vendors/azure/azure.vendor.ts b/src/modules/llms/vendors/azure/azure.vendor.ts index b511c5e6f..bde413011 100644 --- a/src/modules/llms/vendors/azure/azure.vendor.ts +++ b/src/modules/llms/vendors/azure/azure.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { AzureIcon } from '~/common/components/icons/vendors/AzureIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -41,7 +39,7 @@ export const ModelVendorAzure: IModelVendor backendCaps().hasLlmAzureOpenAI, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmAzureOpenAI, // components Icon: AzureIcon, diff --git a/src/modules/llms/vendors/gemini/GeminiSourceSetup.tsx b/src/modules/llms/vendors/gemini/GeminiSourceSetup.tsx index bc2468472..767d2df52 100644 --- a/src/modules/llms/vendors/gemini/GeminiSourceSetup.tsx +++ b/src/modules/llms/vendors/gemini/GeminiSourceSetup.tsx @@ -31,13 +31,12 @@ const SAFETY_OPTIONS: { value: GeminiBlockSafetyLevel, label: string }[] = [ export function GeminiSourceSetup(props: { sourceId: DModelSourceId }) { // external state - const { source, sourceSetupValid, access, updateSetup } = + const { source, sourceSetupValid, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorGemini); // derived state const { geminiKey, minSafetyLevel } = access; - const needsUserKey = !ModelVendorGemini.hasBackendCap?.(); const shallFetchSucceed = !needsUserKey || (!!geminiKey && sourceSetupValid); const showKeyError = !!geminiKey && !sourceSetupValid; diff --git a/src/modules/llms/vendors/gemini/gemini.vendor.ts b/src/modules/llms/vendors/gemini/gemini.vendor.ts index 817a50232..ce5c19117 100644 --- a/src/modules/llms/vendors/gemini/gemini.vendor.ts +++ b/src/modules/llms/vendors/gemini/gemini.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { GeminiIcon } from '~/common/components/icons/vendors/GeminiIcon'; import { apiAsync, apiQuery } from '~/common/util/trpc.client'; @@ -37,7 +35,7 @@ export const ModelVendorGemini: IModelVendor backendCaps().hasLlmGemini, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmGemini, // components Icon: GeminiIcon, diff --git a/src/modules/llms/vendors/groq/GroqSourceSetup.tsx b/src/modules/llms/vendors/groq/GroqSourceSetup.tsx index 3a6f48347..728419585 100644 --- a/src/modules/llms/vendors/groq/GroqSourceSetup.tsx +++ b/src/modules/llms/vendors/groq/GroqSourceSetup.tsx @@ -21,14 +21,13 @@ export function GroqSourceSetup(props: { sourceId: DModelSourceId }) { // external state const { source, access, - sourceSetupValid, updateSetup, + sourceSetupValid, hasNoBackendCap: needsUserKey, updateSetup, } = useSourceSetup(props.sourceId, ModelVendorGroq); // derived state const { oaiKey: groqKey } = access; // key validation - const needsUserKey = !ModelVendorGroq.hasBackendCap?.(); const shallFetchSucceed = !needsUserKey || (!!groqKey && sourceSetupValid); const showKeyError = !!groqKey && !sourceSetupValid; diff --git a/src/modules/llms/vendors/groq/groq.vendor.ts b/src/modules/llms/vendors/groq/groq.vendor.ts index a37f227b7..3b85dcc25 100644 --- a/src/modules/llms/vendors/groq/groq.vendor.ts +++ b/src/modules/llms/vendors/groq/groq.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { GroqIcon } from '~/common/components/icons/vendors/GroqIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -21,7 +19,7 @@ export const ModelVendorGroq: IModelVendor backendCaps().hasLlmGroq, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmGroq, // components Icon: GroqIcon, diff --git a/src/modules/llms/vendors/localai/LocalAISourceSetup.tsx b/src/modules/llms/vendors/localai/LocalAISourceSetup.tsx index 3477e6fa9..3fc3c9360 100644 --- a/src/modules/llms/vendors/localai/LocalAISourceSetup.tsx +++ b/src/modules/llms/vendors/localai/LocalAISourceSetup.tsx @@ -4,7 +4,7 @@ import { z } from 'zod'; import { Button, Typography } from '@mui/joy'; import CheckBoxOutlinedIcon from '@mui/icons-material/CheckBoxOutlined'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { ExpanderAccordion } from '~/common/components/ExpanderAccordion'; import { FormInputKey } from '~/common/components/forms/FormInputKey'; @@ -29,7 +29,7 @@ export function LocalAISourceSetup(props: { sourceId: DModelSourceId }) { const [adminOpen, setAdminOpen] = React.useState(false); // external state - const { hasLlmLocalAIHost: backendHasHost, hasLlmLocalAIKey: backendHasKey } = backendCaps(); + const { hasLlmLocalAIHost: backendHasHost, hasLlmLocalAIKey: backendHasKey } = backendCapabilities(); const { source, access, updateSetup } = useSourceSetup(props.sourceId, ModelVendorLocalAI); diff --git a/src/modules/llms/vendors/localai/localai.vendor.ts b/src/modules/llms/vendors/localai/localai.vendor.ts index 3e323f3d3..228503e9b 100644 --- a/src/modules/llms/vendors/localai/localai.vendor.ts +++ b/src/modules/llms/vendors/localai/localai.vendor.ts @@ -7,7 +7,6 @@ import { LLMOptionsOpenAI, ModelVendorOpenAI } from '../openai/openai.vendor'; import { OpenAILLMOptions } from '../openai/OpenAILLMOptions'; import { LocalAISourceSetup } from './LocalAISourceSetup'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; export interface SourceSetupLocalAI { @@ -21,10 +20,9 @@ export const ModelVendorLocalAI: IModelVendor { + hasBackendCap: (backendCapabilities) => { // this is to show the green mark on the vendor icon in the setup screen - const { hasLlmLocalAIHost, hasLlmLocalAIKey } = backendCaps(); - return hasLlmLocalAIHost || hasLlmLocalAIKey; + return backendCapabilities.hasLlmLocalAIHost || backendCapabilities.hasLlmLocalAIKey; }, // components diff --git a/src/modules/llms/vendors/mistral/MistralSourceSetup.tsx b/src/modules/llms/vendors/mistral/MistralSourceSetup.tsx index 73ac8e140..e1c90d860 100644 --- a/src/modules/llms/vendors/mistral/MistralSourceSetup.tsx +++ b/src/modules/llms/vendors/mistral/MistralSourceSetup.tsx @@ -20,13 +20,12 @@ const MISTRAL_REG_LINK = 'https://console.mistral.ai/'; export function MistralSourceSetup(props: { sourceId: DModelSourceId }) { // external state - const { source, sourceSetupValid, access, updateSetup } = + const { source, sourceSetupValid, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorMistral); // derived state const { oaiKey: mistralKey } = access; - const needsUserKey = !ModelVendorMistral.hasBackendCap?.(); const shallFetchSucceed = !needsUserKey || (!!mistralKey && sourceSetupValid); const showKeyError = !!mistralKey && !sourceSetupValid; diff --git a/src/modules/llms/vendors/mistral/mistral.vendor.ts b/src/modules/llms/vendors/mistral/mistral.vendor.ts index 449d1bb4a..7d7b52ad9 100644 --- a/src/modules/llms/vendors/mistral/mistral.vendor.ts +++ b/src/modules/llms/vendors/mistral/mistral.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { MistralIcon } from '~/common/components/icons/vendors/MistralIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -24,7 +22,7 @@ export const ModelVendorMistral: IModelVendor backendCaps().hasLlmMistral, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmMistral, // components Icon: MistralIcon, diff --git a/src/modules/llms/vendors/ollama/ollama.vendor.ts b/src/modules/llms/vendors/ollama/ollama.vendor.ts index 6b0d3b171..3b5e78bee 100644 --- a/src/modules/llms/vendors/ollama/ollama.vendor.ts +++ b/src/modules/llms/vendors/ollama/ollama.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { OllamaIcon } from '~/common/components/icons/vendors/OllamaIcon'; import { apiAsync, apiQuery } from '~/common/util/trpc.client'; @@ -25,7 +23,7 @@ export const ModelVendorOllama: IModelVendor backendCaps().hasLlmOllama, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmOllama, // components Icon: OllamaIcon, diff --git a/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx b/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx index 86656edb3..9034d4fcc 100644 --- a/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx +++ b/src/modules/llms/vendors/openai/OpenAISourceSetup.tsx @@ -28,13 +28,12 @@ export function OpenAISourceSetup(props: { sourceId: DModelSourceId }) { const advanced = useToggleableBoolean(!!props.sourceId?.includes('-')); // external state - const { source, sourceHasLLMs, access, updateSetup } = + const { source, sourceHasLLMs, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorOpenAI); // derived state const { oaiKey, oaiOrg, oaiHost, heliKey, moderationCheck } = access; - const needsUserKey = !ModelVendorOpenAI.hasBackendCap?.(); const keyValid = isValidOpenAIApiKey(oaiKey); const keyError = (/*needsUserKey ||*/ !!oaiKey) && !keyValid; const shallFetchSucceed = oaiKey ? keyValid : !needsUserKey; diff --git a/src/modules/llms/vendors/openai/openai.vendor.ts b/src/modules/llms/vendors/openai/openai.vendor.ts index 93db9039d..8b22a8c2b 100644 --- a/src/modules/llms/vendors/openai/openai.vendor.ts +++ b/src/modules/llms/vendors/openai/openai.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { OpenAIIcon } from '~/common/components/icons/vendors/OpenAIIcon'; import { apiAsync, apiQuery } from '~/common/util/trpc.client'; @@ -40,7 +38,7 @@ export const ModelVendorOpenAI: IModelVendor backendCaps().hasLlmOpenAI, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmOpenAI, // components Icon: OpenAIIcon, diff --git a/src/modules/llms/vendors/openrouter/OpenRouterSourceSetup.tsx b/src/modules/llms/vendors/openrouter/OpenRouterSourceSetup.tsx index 9ffc8ebf6..f40960fe6 100644 --- a/src/modules/llms/vendors/openrouter/OpenRouterSourceSetup.tsx +++ b/src/modules/llms/vendors/openrouter/OpenRouterSourceSetup.tsx @@ -18,13 +18,12 @@ import { isValidOpenRouterKey, ModelVendorOpenRouter } from './openrouter.vendor export function OpenRouterSourceSetup(props: { sourceId: DModelSourceId }) { // external state - const { source, sourceHasLLMs, access, updateSetup } = + const { source, sourceHasLLMs, access, hasNoBackendCap: needsUserKey, updateSetup } = useSourceSetup(props.sourceId, ModelVendorOpenRouter); // derived state const { oaiKey } = access; - const needsUserKey = !ModelVendorOpenRouter.hasBackendCap?.(); const keyValid = isValidOpenRouterKey(oaiKey); const keyError = (/*needsUserKey ||*/ !!oaiKey) && !keyValid; const shallFetchSucceed = oaiKey ? keyValid : !needsUserKey; diff --git a/src/modules/llms/vendors/openrouter/openrouter.vendor.ts b/src/modules/llms/vendors/openrouter/openrouter.vendor.ts index 5b19d8ea6..2826eaa61 100644 --- a/src/modules/llms/vendors/openrouter/openrouter.vendor.ts +++ b/src/modules/llms/vendors/openrouter/openrouter.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { OpenRouterIcon } from '~/common/components/icons/vendors/OpenRouterIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -38,7 +36,7 @@ export const ModelVendorOpenRouter: IModelVendor backendCaps().hasLlmOpenRouter, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmOpenRouter, // components Icon: OpenRouterIcon, diff --git a/src/modules/llms/vendors/perplexity/PerplexitySourceSetup.tsx b/src/modules/llms/vendors/perplexity/PerplexitySourceSetup.tsx index 804f53d88..f3b4cad74 100644 --- a/src/modules/llms/vendors/perplexity/PerplexitySourceSetup.tsx +++ b/src/modules/llms/vendors/perplexity/PerplexitySourceSetup.tsx @@ -21,14 +21,13 @@ export function PerplexitySourceSetup(props: { sourceId: DModelSourceId }) { // external state const { source, access, - sourceSetupValid, updateSetup, + sourceSetupValid, hasNoBackendCap: needsUserKey, updateSetup, } = useSourceSetup(props.sourceId, ModelVendorPerplexity); // derived state const { oaiKey: perplexityKey } = access; // key validation - const needsUserKey = !ModelVendorPerplexity.hasBackendCap?.(); const shallFetchSucceed = !needsUserKey || (!!perplexityKey && sourceSetupValid); const showKeyError = !!perplexityKey && !sourceSetupValid; diff --git a/src/modules/llms/vendors/perplexity/perplexity.vendor.ts b/src/modules/llms/vendors/perplexity/perplexity.vendor.ts index f15327235..c1868f7ac 100644 --- a/src/modules/llms/vendors/perplexity/perplexity.vendor.ts +++ b/src/modules/llms/vendors/perplexity/perplexity.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { PerplexityIcon } from '~/common/components/icons/vendors/PerplexityIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -21,7 +19,7 @@ export const ModelVendorPerplexity: IModelVendor backendCaps().hasLlmPerplexity, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmPerplexity, // components Icon: PerplexityIcon, diff --git a/src/modules/llms/vendors/togetherai/TogetherAISourceSetup.tsx b/src/modules/llms/vendors/togetherai/TogetherAISourceSetup.tsx index de641042c..a4c3e53cc 100644 --- a/src/modules/llms/vendors/togetherai/TogetherAISourceSetup.tsx +++ b/src/modules/llms/vendors/togetherai/TogetherAISourceSetup.tsx @@ -27,14 +27,13 @@ export function TogetherAISourceSetup(props: { sourceId: DModelSourceId }) { // external state const { source, access, - partialSetup, sourceSetupValid, updateSetup, + partialSetup, sourceSetupValid, hasNoBackendCap: needsUserKey, updateSetup, } = useSourceSetup(props.sourceId, ModelVendorTogetherAI); // derived state const { oaiKey: togetherKey } = access; // validate if url is a well formed proper url with zod - const needsUserKey = !ModelVendorTogetherAI.hasBackendCap?.(); const shallFetchSucceed = !needsUserKey || (!!togetherKey && sourceSetupValid); const showKeyError = !!togetherKey && !sourceSetupValid; diff --git a/src/modules/llms/vendors/togetherai/togetherai.vendor.ts b/src/modules/llms/vendors/togetherai/togetherai.vendor.ts index e8f7b823e..945379682 100644 --- a/src/modules/llms/vendors/togetherai/togetherai.vendor.ts +++ b/src/modules/llms/vendors/togetherai/togetherai.vendor.ts @@ -1,5 +1,3 @@ -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; - import { TogetherIcon } from '~/common/components/icons/vendors/TogetherIcon'; import type { IModelVendor } from '../IModelVendor'; @@ -23,7 +21,7 @@ export const ModelVendorTogetherAI: IModelVendor backendCaps().hasLlmTogetherAI, + hasBackendCap: (backendCapabilities) => backendCapabilities.hasLlmTogetherAI, // components Icon: TogetherIcon, diff --git a/src/modules/llms/vendors/useSourceSetup.ts b/src/modules/llms/vendors/useSourceSetup.ts index bfc320a96..07f78c507 100644 --- a/src/modules/llms/vendors/useSourceSetup.ts +++ b/src/modules/llms/vendors/useSourceSetup.ts @@ -1,5 +1,7 @@ import { shallow } from 'zustand/shallow'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; + import type { IModelVendor } from './IModelVendor'; import { DModelSource, DModelSourceId, useModelsStore } from '../store-llms'; @@ -12,6 +14,8 @@ export function useSourceSetup(sourceId: DMo // invalidates only when the setup changes const { updateSourceSetup, ...rest } = useModelsStore(state => { + const hasNoBackendCap = !vendor.hasBackendCap?.(backendCapabilities()); + // find the source (or null) const source: DModelSource | null = state.sources.find(source => source.id === sourceId) as DModelSource ?? null; @@ -21,6 +25,7 @@ export function useSourceSetup(sourceId: DMo const access = vendor.getTransportAccess(source?.setup); return { + hasNoBackendCap, source, partialSetup: source?.setup ?? null, // NOTE: do not use - prefer ACCESS; only used in 1 edge case now access, diff --git a/src/modules/t2i/prodia/ProdiaSettings.tsx b/src/modules/t2i/prodia/ProdiaSettings.tsx index 39aa7b1ac..0f5e8c75e 100644 --- a/src/modules/t2i/prodia/ProdiaSettings.tsx +++ b/src/modules/t2i/prodia/ProdiaSettings.tsx @@ -8,7 +8,7 @@ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import StayPrimaryLandscapeIcon from '@mui/icons-material/StayPrimaryLandscape'; import StayPrimaryPortraitIcon from '@mui/icons-material/StayPrimaryPortrait'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { FormInputKey } from '~/common/components/forms/FormInputKey'; import { FormLabelStart } from '~/common/components/forms/FormLabelStart'; @@ -29,7 +29,7 @@ export function ProdiaSettings(props: { noSkipKey?: boolean }) { const advanced = useToggleableBoolean(false, 'ProdiaSettings'); // external state - const backendHasProdia = backendCaps().hasImagingProdia; + const backendHasProdia = backendCapabilities().hasImagingProdia; const { apiKey, setApiKey, modelId, setModelId, modelGen, setModelGen, negativePrompt, setNegativePrompt, steps, setSteps, cfgScale, setCfgScale, prodiaAspectRatio, setProdiaAspectRatio, upscale, setUpscale, prodiaResolution, setProdiaResolution, seed, setSeed } = useProdiaStore(state => ({ apiKey: state.prodiaApiKey, setApiKey: state.setProdiaApiKey, modelId: state.prodiaModelId, setModelId: state.setProdiaModelId, diff --git a/src/modules/t2i/t2i.client.ts b/src/modules/t2i/t2i.client.ts index 0158006f1..2204eb333 100644 --- a/src/modules/t2i/t2i.client.ts +++ b/src/modules/t2i/t2i.client.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { shallow } from 'zustand/shallow'; import { DLLM, DModelSource, DModelSourceId, useModelsStore } from '~/modules/llms/store-llms'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import type { CapabilityTextToImage, TextToImageProvider } from '~/common/components/useCapabilities'; @@ -85,7 +85,7 @@ export async function t2iGenerateImageOrThrow(provider: TextToImageProvider, pro return await openAIGenerateImagesOrThrow(provider.id, prompt, count); case 'prodia': - const hasProdiaServer = backendCaps().hasImagingProdia; + const hasProdiaServer = backendCapabilities().hasImagingProdia; const hasProdiaClientModels = !!useProdiaStore.getState().prodiaModelId; if (!hasProdiaServer && !hasProdiaClientModels) throw new Error('No Prodia configuration found for TextToImage'); @@ -127,7 +127,7 @@ function getTextToImageProviders(openAIModelSources: OpenAIModelSource[], hasPro } // add Prodia - const hasProdiaServer = backendCaps().hasImagingProdia; + const hasProdiaServer = backendCapabilities().hasImagingProdia; providers.push({ id: 'prodia', label: 'Prodia', diff --git a/src/modules/trade/ExportChats.tsx b/src/modules/trade/ExportChats.tsx index b37441218..a765b4e8e 100644 --- a/src/modules/trade/ExportChats.tsx +++ b/src/modules/trade/ExportChats.tsx @@ -4,7 +4,7 @@ import { Box, Button, Grid, Typography } from '@mui/joy'; import DoneIcon from '@mui/icons-material/Done'; import FileDownloadIcon from '@mui/icons-material/FileDownload'; -import { backendCaps } from '~/modules/backend/store-backend-capabilities'; +import { backendCapabilities } from '~/modules/backend/store-backend-capabilities'; import { DConversationId, getConversation } from '~/common/state/store-chats'; @@ -31,7 +31,7 @@ export function ExportChats(props: { config: ExportConfig, onClose: () => void } const [downloadedAllState, setDownloadedAllState] = React.useState<'ok' | 'fail' | null>(null); // external state - const enableSharing = backendCaps().hasDB; + const enableSharing = backendCapabilities().hasDB; // derived state const { exportAll } = props.config;