diff --git a/src/renderer/src/hooks/useProvider.ts b/src/renderer/src/hooks/useProvider.ts index be4ed772fb..960d2929d0 100644 --- a/src/renderer/src/hooks/useProvider.ts +++ b/src/renderer/src/hooks/useProvider.ts @@ -13,12 +13,28 @@ import { } from '@renderer/store/llm' import type { Assistant, Model, Provider } from '@renderer/types' import { isSystemProvider } from '@renderer/types' +import { withoutTrailingSlash } from '@renderer/utils/api' import { useDefaultModel } from './useAssistant' +/** + * Normalizes provider apiHost by removing trailing slashes. + * This ensures consistent URL concatenation across the application. + */ +function normalizeProvider(provider: T): T { + return { + ...provider, + apiHost: withoutTrailingSlash(provider.apiHost) + } +} + const selectEnabledProviders = createSelector( (state) => state.llm.providers, - (providers) => providers.filter((p) => p.enabled).concat(CHERRYAI_PROVIDER) + (providers) => + providers + .map(normalizeProvider) + .filter((p) => p.enabled) + .concat(CHERRYAI_PROVIDER) ) export function useProviders() { @@ -35,21 +51,25 @@ export function useProviders() { } export function useSystemProviders() { - return useAppSelector((state) => state.llm.providers.filter((p) => isSystemProvider(p))) + return useAppSelector((state) => state.llm.providers.filter((p) => isSystemProvider(p)).map(normalizeProvider)) } export function useUserProviders() { - return useAppSelector((state) => state.llm.providers.filter((p) => !isSystemProvider(p))) + return useAppSelector((state) => state.llm.providers.filter((p) => !isSystemProvider(p)).map(normalizeProvider)) } export function useAllProviders() { - return useAppSelector((state) => state.llm.providers) + return useAppSelector((state) => state.llm.providers.map(normalizeProvider)) } export function useProvider(id: string) { const provider = - useAppSelector((state) => state.llm.providers.concat([CHERRYAI_PROVIDER]).find((p) => p.id === id)) || - getDefaultProvider() + useAppSelector((state) => + state.llm.providers + .concat([CHERRYAI_PROVIDER]) + .map(normalizeProvider) + .find((p) => p.id === id) + ) || getDefaultProvider() const dispatch = useAppDispatch() return {