mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🔧 refactor: Enhance Model & Endpoint Configurations with Global Indicators 🌍 (#6578)
* 🔧 fix: Simplify event handling in Badge component by always preventing default behavior and stopping propagation on toggle
* feat: show Global agents icon in ModelSelector
* feat: show Global agents icon in ModelSelector's search results
* refactor(Header): remove unused import
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* refactor(EndpointModelItem): remove unused import of useGetStartupConfig
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
b9ebdd4aa5
commit
e630c0a00d
13 changed files with 76 additions and 127 deletions
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TModelSpec, TInterfaceConfig } from 'librechat-data-provider';
|
import { TModelSpec, TStartupConfig } from 'librechat-data-provider';
|
||||||
|
|
||||||
export interface Endpoint {
|
export interface Endpoint {
|
||||||
value: string;
|
value: string;
|
||||||
label: string;
|
label: string;
|
||||||
hasModels: boolean;
|
hasModels: boolean;
|
||||||
models?: string[];
|
models?: Array<{ name: string; isGlobal?: boolean }>;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
agentNames?: Record<string, string>;
|
agentNames?: Record<string, string>;
|
||||||
assistantNames?: Record<string, string>;
|
assistantNames?: Record<string, string>;
|
||||||
|
|
@ -19,6 +19,6 @@ export interface SelectedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModelSelectorProps {
|
export interface ModelSelectorProps {
|
||||||
interfaceConfig: TInterfaceConfig;
|
startupConfig: TStartupConfig | undefined;
|
||||||
modelSpecs: TModelSpec[];
|
modelSpecs: TModelSpec[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -496,17 +496,6 @@ export interface ExtendedFile {
|
||||||
metadata?: t.TFile['metadata'];
|
metadata?: t.TFile['metadata'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExtendedEndpoint {
|
|
||||||
value: EModelEndpoint;
|
|
||||||
label: string;
|
|
||||||
hasModels: boolean;
|
|
||||||
icon: JSX.Element | null;
|
|
||||||
models?: string[];
|
|
||||||
agentNames?: Record<string, string>;
|
|
||||||
assistantNames?: Record<string, string>;
|
|
||||||
modelIcons?: Record<string, string | undefined>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ModelItemProps {
|
export interface ModelItemProps {
|
||||||
modelName: string;
|
modelName: string;
|
||||||
endpoint: EModelEndpoint;
|
endpoint: EModelEndpoint;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import ExportAndShareMenu from './ExportAndShareMenu';
|
||||||
import { useMediaQuery, useHasAccess } from '~/hooks';
|
import { useMediaQuery, useHasAccess } from '~/hooks';
|
||||||
import BookmarkMenu from './Menus/BookmarkMenu';
|
import BookmarkMenu from './Menus/BookmarkMenu';
|
||||||
import AddMultiConvo from './AddMultiConvo';
|
import AddMultiConvo from './AddMultiConvo';
|
||||||
|
|
||||||
const defaultInterface = getConfigDefaults().interface;
|
const defaultInterface = getConfigDefaults().interface;
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
|
|
@ -38,7 +37,7 @@ export default function Header() {
|
||||||
<div className="hide-scrollbar flex w-full items-center justify-between gap-2 overflow-x-auto">
|
<div className="hide-scrollbar flex w-full items-center justify-between gap-2 overflow-x-auto">
|
||||||
<div className="mx-2 flex items-center gap-2">
|
<div className="mx-2 flex items-center gap-2">
|
||||||
{!navVisible && <HeaderNewChat />}
|
{!navVisible && <HeaderNewChat />}
|
||||||
{<ModelSelector interfaceConfig={interfaceConfig} modelSpecs={modelSpecs} />}
|
{<ModelSelector startupConfig={startupConfig} modelSpecs={modelSpecs} />}
|
||||||
{interfaceConfig.presets === true && interfaceConfig.modelSelect && <PresetsMenu />}
|
{interfaceConfig.presets === true && interfaceConfig.modelSelect && <PresetsMenu />}
|
||||||
{hasAccessToBookmarks === true && <BookmarkMenu />}
|
{hasAccessToBookmarks === true && <BookmarkMenu />}
|
||||||
{hasAccessToMultiConvo === true && <AddMultiConvo />}
|
{hasAccessToMultiConvo === true && <AddMultiConvo />}
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,9 @@ function ModelSelectorContent() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ModelSelector({ interfaceConfig, modelSpecs }: ModelSelectorProps) {
|
export default function ModelSelector({ startupConfig, modelSpecs }: ModelSelectorProps) {
|
||||||
return (
|
return (
|
||||||
<ModelSelectorProvider modelSpecs={modelSpecs} interfaceConfig={interfaceConfig}>
|
<ModelSelectorProvider modelSpecs={modelSpecs} startupConfig={startupConfig}>
|
||||||
<ModelSelectorContent />
|
<ModelSelectorContent />
|
||||||
</ModelSelectorProvider>
|
</ModelSelectorProvider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,13 @@ export function useModelSelectorContext() {
|
||||||
interface ModelSelectorProviderProps {
|
interface ModelSelectorProviderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
modelSpecs: t.TModelSpec[];
|
modelSpecs: t.TModelSpec[];
|
||||||
interfaceConfig: t.TInterfaceConfig;
|
startupConfig: t.TStartupConfig | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ModelSelectorProvider({
|
export function ModelSelectorProvider({
|
||||||
children,
|
children,
|
||||||
modelSpecs,
|
modelSpecs,
|
||||||
interfaceConfig,
|
startupConfig,
|
||||||
}: ModelSelectorProviderProps) {
|
}: ModelSelectorProviderProps) {
|
||||||
const agentsMap = useAgentsMapContext();
|
const agentsMap = useAgentsMapContext();
|
||||||
const assistantsMap = useAssistantsMapContext();
|
const assistantsMap = useAssistantsMapContext();
|
||||||
|
|
@ -61,7 +61,7 @@ export function ModelSelectorProvider({
|
||||||
agentsMap,
|
agentsMap,
|
||||||
assistantsMap,
|
assistantsMap,
|
||||||
endpointsConfig,
|
endpointsConfig,
|
||||||
interfaceConfig,
|
startupConfig,
|
||||||
});
|
});
|
||||||
const { onSelectEndpoint, onSelectSpec } = useSelectMention({
|
const { onSelectEndpoint, onSelectSpec } = useSelectMention({
|
||||||
// presets,
|
// presets,
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,13 @@ export function EndpointItem({ endpoint }: EndpointItemProps) {
|
||||||
|
|
||||||
if (endpoint.hasModels) {
|
if (endpoint.hasModels) {
|
||||||
const filteredModels = searchValue
|
const filteredModels = searchValue
|
||||||
? filterModels(endpoint, endpoint.models || [], searchValue, agentsMap, assistantsMap)
|
? filterModels(
|
||||||
|
endpoint,
|
||||||
|
(endpoint.models || []).map((model) => model.name),
|
||||||
|
searchValue,
|
||||||
|
agentsMap,
|
||||||
|
assistantsMap,
|
||||||
|
)
|
||||||
: null;
|
: null;
|
||||||
const placeholder =
|
const placeholder =
|
||||||
isAgentsEndpoint(endpoint.value) || isAssistantsEndpoint(endpoint.value)
|
isAgentsEndpoint(endpoint.value) || isAssistantsEndpoint(endpoint.value)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { EarthIcon } from 'lucide-react';
|
||||||
import { isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import type { Endpoint } from '~/common';
|
import type { Endpoint } from '~/common';
|
||||||
import { useModelSelectorContext } from '../ModelSelectorContext';
|
import { useModelSelectorContext } from '../ModelSelectorContext';
|
||||||
|
|
@ -12,12 +13,16 @@ interface EndpointModelItemProps {
|
||||||
|
|
||||||
export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointModelItemProps) {
|
export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointModelItemProps) {
|
||||||
const { handleSelectModel } = useModelSelectorContext();
|
const { handleSelectModel } = useModelSelectorContext();
|
||||||
|
let isGlobal = false;
|
||||||
let modelName = modelId;
|
let modelName = modelId;
|
||||||
const avatarUrl = endpoint?.modelIcons?.[modelId ?? ''] || null;
|
const avatarUrl = endpoint?.modelIcons?.[modelId ?? ''] || null;
|
||||||
|
|
||||||
// Use custom names if available
|
// Use custom names if available
|
||||||
if (endpoint && modelId && isAgentsEndpoint(endpoint.value) && endpoint.agentNames?.[modelId]) {
|
if (endpoint && modelId && isAgentsEndpoint(endpoint.value) && endpoint.agentNames?.[modelId]) {
|
||||||
modelName = endpoint.agentNames[modelId];
|
modelName = endpoint.agentNames[modelId];
|
||||||
|
|
||||||
|
const modelInfo = endpoint?.models?.find((m) => m.name === modelId);
|
||||||
|
isGlobal = modelInfo?.isGlobal ?? false;
|
||||||
} else if (
|
} else if (
|
||||||
endpoint &&
|
endpoint &&
|
||||||
modelId &&
|
modelId &&
|
||||||
|
|
@ -46,6 +51,7 @@ export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointMod
|
||||||
) : null}
|
) : null}
|
||||||
<span>{modelName}</span>
|
<span>{modelName}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{isGlobal && <EarthIcon className="ml-auto size-4 text-green-400" />}
|
||||||
{isSelected && (
|
{isSelected && (
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
|
|
@ -53,7 +59,7 @@ export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointMod
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
className="ml-auto block"
|
className="block"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -69,11 +75,11 @@ export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointMod
|
||||||
|
|
||||||
export function renderEndpointModels(
|
export function renderEndpointModels(
|
||||||
endpoint: Endpoint | null,
|
endpoint: Endpoint | null,
|
||||||
models: string[],
|
models: Array<{ name: string; isGlobal?: boolean }>,
|
||||||
selectedModel: string | null,
|
selectedModel: string | null,
|
||||||
filteredModels?: string[],
|
filteredModels?: string[],
|
||||||
) {
|
) {
|
||||||
const modelsToRender = filteredModels || models;
|
const modelsToRender = filteredModels || models.map((model) => model.name);
|
||||||
|
|
||||||
return modelsToRender.map(
|
return modelsToRender.map(
|
||||||
(modelId) =>
|
(modelId) =>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
import { EarthIcon } from 'lucide-react';
|
||||||
import { isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import type { TModelSpec } from 'librechat-data-provider';
|
import type { TModelSpec } from 'librechat-data-provider';
|
||||||
import type { Endpoint } from '~/common';
|
import type { Endpoint } from '~/common';
|
||||||
|
|
@ -20,8 +21,6 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
handleSelectModel,
|
handleSelectModel,
|
||||||
handleSelectEndpoint,
|
handleSelectEndpoint,
|
||||||
endpointsConfig,
|
endpointsConfig,
|
||||||
agentsMap,
|
|
||||||
assistantsMap,
|
|
||||||
} = useModelSelectorContext();
|
} = useModelSelectorContext();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -102,20 +101,20 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
const lowerQuery = searchValue.toLowerCase();
|
const lowerQuery = searchValue.toLowerCase();
|
||||||
const filteredModels = endpoint.label.toLowerCase().includes(lowerQuery)
|
const filteredModels = endpoint.label.toLowerCase().includes(lowerQuery)
|
||||||
? endpoint.models
|
? endpoint.models
|
||||||
: endpoint.models.filter((modelId) => {
|
: endpoint.models.filter((model) => {
|
||||||
let modelName = modelId;
|
let modelName = model.name;
|
||||||
if (
|
if (
|
||||||
isAgentsEndpoint(endpoint.value) &&
|
isAgentsEndpoint(endpoint.value) &&
|
||||||
endpoint.agentNames &&
|
endpoint.agentNames &&
|
||||||
endpoint.agentNames[modelId]
|
endpoint.agentNames[model.name]
|
||||||
) {
|
) {
|
||||||
modelName = endpoint.agentNames[modelId];
|
modelName = endpoint.agentNames[model.name];
|
||||||
} else if (
|
} else if (
|
||||||
isAssistantsEndpoint(endpoint.value) &&
|
isAssistantsEndpoint(endpoint.value) &&
|
||||||
endpoint.assistantNames &&
|
endpoint.assistantNames &&
|
||||||
endpoint.assistantNames[modelId]
|
endpoint.assistantNames[model.name]
|
||||||
) {
|
) {
|
||||||
modelName = endpoint.assistantNames[modelId];
|
modelName = endpoint.assistantNames[model.name];
|
||||||
}
|
}
|
||||||
return modelName.toLowerCase().includes(lowerQuery);
|
return modelName.toLowerCase().includes(lowerQuery);
|
||||||
});
|
});
|
||||||
|
|
@ -134,7 +133,10 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
)}
|
)}
|
||||||
{endpoint.label}
|
{endpoint.label}
|
||||||
</div>
|
</div>
|
||||||
{filteredModels.map((modelId) => {
|
{filteredModels.map((model) => {
|
||||||
|
const modelId = model.name;
|
||||||
|
|
||||||
|
let isGlobal = false;
|
||||||
let modelName = modelId;
|
let modelName = modelId;
|
||||||
if (
|
if (
|
||||||
isAgentsEndpoint(endpoint.value) &&
|
isAgentsEndpoint(endpoint.value) &&
|
||||||
|
|
@ -142,6 +144,8 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
endpoint.agentNames[modelId]
|
endpoint.agentNames[modelId]
|
||||||
) {
|
) {
|
||||||
modelName = endpoint.agentNames[modelId];
|
modelName = endpoint.agentNames[modelId];
|
||||||
|
const modelInfo = endpoint?.models?.find((m) => m.name === modelId);
|
||||||
|
isGlobal = modelInfo?.isGlobal ?? false;
|
||||||
} else if (
|
} else if (
|
||||||
isAssistantsEndpoint(endpoint.value) &&
|
isAssistantsEndpoint(endpoint.value) &&
|
||||||
endpoint.assistantNames &&
|
endpoint.assistantNames &&
|
||||||
|
|
@ -168,6 +172,7 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
)}
|
)}
|
||||||
<span>{modelName}</span>
|
<span>{modelName}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{isGlobal && <EarthIcon className="ml-auto size-4 text-green-400" />}
|
||||||
{selectedEndpoint === endpoint.value && selectedModel === modelId && (
|
{selectedEndpoint === endpoint.value && selectedModel === modelId && (
|
||||||
<svg
|
<svg
|
||||||
width="16"
|
width="16"
|
||||||
|
|
@ -175,7 +180,7 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
className="ml-auto block"
|
className="block"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,12 @@ import SpecIcon from '~/components/Chat/Menus/Endpoints/components/SpecIcon';
|
||||||
import { Endpoint, SelectedValues } from '~/common';
|
import { Endpoint, SelectedValues } from '~/common';
|
||||||
|
|
||||||
export function filterItems<
|
export function filterItems<
|
||||||
T extends { label: string; name?: string; value?: string; models?: string[] },
|
T extends {
|
||||||
|
label: string;
|
||||||
|
name?: string;
|
||||||
|
value?: string;
|
||||||
|
models?: Array<{ name: string; isGlobal?: boolean }>;
|
||||||
|
},
|
||||||
>(
|
>(
|
||||||
items: T[],
|
items: T[],
|
||||||
searchValue: string,
|
searchValue: string,
|
||||||
|
|
@ -36,18 +41,18 @@ export function filterItems<
|
||||||
|
|
||||||
if (item.models && item.models.length > 0) {
|
if (item.models && item.models.length > 0) {
|
||||||
return item.models.some((modelId) => {
|
return item.models.some((modelId) => {
|
||||||
if (modelId.toLowerCase().includes(searchTermLower)) {
|
if (modelId.name.toLowerCase().includes(searchTermLower)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAgentsEndpoint(item.value) && agentsMap && modelId in agentsMap) {
|
if (isAgentsEndpoint(item.value) && agentsMap && modelId.name in agentsMap) {
|
||||||
const agentName = agentsMap[modelId]?.name;
|
const agentName = agentsMap[modelId.name]?.name;
|
||||||
return typeof agentName === 'string' && agentName.toLowerCase().includes(searchTermLower);
|
return typeof agentName === 'string' && agentName.toLowerCase().includes(searchTermLower);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAssistantsEndpoint(item.value) && assistantsMap) {
|
if (isAssistantsEndpoint(item.value) && assistantsMap) {
|
||||||
const endpoint = item.value ?? '';
|
const endpoint = item.value ?? '';
|
||||||
const assistant = assistantsMap[endpoint][modelId];
|
const assistant = assistantsMap[endpoint][modelId.name];
|
||||||
if (assistant && typeof assistant.name === 'string') {
|
if (assistant && typeof assistant.name === 'string') {
|
||||||
return assistant.name.toLowerCase().includes(searchTermLower);
|
return assistant.name.toLowerCase().includes(searchTermLower);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,7 @@ export default function Badge({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEditing && onToggle) {
|
if (!isEditing && onToggle) {
|
||||||
if (typeof window !== 'undefined' && window.innerWidth >= 768) {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onToggle();
|
onToggle();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import type {
|
||||||
Assistant,
|
Assistant,
|
||||||
TEndpointsConfig,
|
TEndpointsConfig,
|
||||||
TAgentsMap,
|
TAgentsMap,
|
||||||
TInterfaceConfig,
|
|
||||||
TAssistantsMap,
|
TAssistantsMap,
|
||||||
|
TStartupConfig,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { ExtendedEndpoint } from '~/common';
|
import type { Endpoint } from '~/common';
|
||||||
import { mapEndpoints, getIconKey, getEndpointField } from '~/utils';
|
import { mapEndpoints, getIconKey, getEndpointField } from '~/utils';
|
||||||
import { useGetEndpointsQuery } from '~/data-provider';
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
|
|
@ -25,16 +25,18 @@ export const useEndpoints = ({
|
||||||
agentsMap,
|
agentsMap,
|
||||||
assistantsMap,
|
assistantsMap,
|
||||||
endpointsConfig,
|
endpointsConfig,
|
||||||
interfaceConfig,
|
startupConfig,
|
||||||
}: {
|
}: {
|
||||||
agentsMap?: TAgentsMap;
|
agentsMap?: TAgentsMap;
|
||||||
assistantsMap?: TAssistantsMap;
|
assistantsMap?: TAssistantsMap;
|
||||||
endpointsConfig: TEndpointsConfig;
|
endpointsConfig: TEndpointsConfig;
|
||||||
interfaceConfig: TInterfaceConfig;
|
startupConfig: TStartupConfig | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
const modelsQuery = useGetModelsQuery();
|
const modelsQuery = useGetModelsQuery();
|
||||||
const { conversation } = useChatContext();
|
const { conversation } = useChatContext();
|
||||||
const { data: endpoints = [] } = useGetEndpointsQuery({ select: mapEndpoints });
|
const { data: endpoints = [] } = useGetEndpointsQuery({ select: mapEndpoints });
|
||||||
|
const { instanceProjectId } = startupConfig ?? {};
|
||||||
|
const interfaceConfig = startupConfig?.interface ?? {};
|
||||||
|
|
||||||
const { endpoint } = conversation ?? {};
|
const { endpoint } = conversation ?? {};
|
||||||
|
|
||||||
|
|
@ -84,7 +86,7 @@ export const useEndpoints = ({
|
||||||
[endpointsConfig],
|
[endpointsConfig],
|
||||||
);
|
);
|
||||||
|
|
||||||
const mappedEndpoints: ExtendedEndpoint[] = useMemo(() => {
|
const mappedEndpoints: Endpoint[] = useMemo(() => {
|
||||||
return filteredEndpoints.map((ep) => {
|
return filteredEndpoints.map((ep) => {
|
||||||
const endpointType = getEndpointField(endpointsConfig, ep, 'type');
|
const endpointType = getEndpointField(endpointsConfig, ep, 'type');
|
||||||
const iconKey = getIconKey({ endpoint: ep, endpointsConfig, endpointType });
|
const iconKey = getIconKey({ endpoint: ep, endpointsConfig, endpointType });
|
||||||
|
|
@ -98,7 +100,7 @@ export const useEndpoints = ({
|
||||||
(modelsQuery.data?.[ep]?.length ?? 0) > 0);
|
(modelsQuery.data?.[ep]?.length ?? 0) > 0);
|
||||||
|
|
||||||
// Base result object with formatted default icon
|
// Base result object with formatted default icon
|
||||||
const result: ExtendedEndpoint = {
|
const result: Endpoint = {
|
||||||
value: ep,
|
value: ep,
|
||||||
label: alternateName[ep] || ep,
|
label: alternateName[ep] || ep,
|
||||||
hasModels,
|
hasModels,
|
||||||
|
|
@ -114,7 +116,11 @@ export const useEndpoints = ({
|
||||||
|
|
||||||
// Handle agents case
|
// Handle agents case
|
||||||
if (ep === EModelEndpoint.agents && agents.length > 0) {
|
if (ep === EModelEndpoint.agents && agents.length > 0) {
|
||||||
result.models = agents.map((agent) => agent.id);
|
result.models = agents.map((agent) => ({
|
||||||
|
name: agent.id,
|
||||||
|
isGlobal:
|
||||||
|
(instanceProjectId != null && agent.projectIds?.includes(instanceProjectId)) ?? false,
|
||||||
|
}));
|
||||||
result.agentNames = agents.reduce((acc, agent) => {
|
result.agentNames = agents.reduce((acc, agent) => {
|
||||||
acc[agent.id] = agent.name || '';
|
acc[agent.id] = agent.name || '';
|
||||||
return acc;
|
return acc;
|
||||||
|
|
@ -127,7 +133,10 @@ export const useEndpoints = ({
|
||||||
|
|
||||||
// Handle assistants case
|
// Handle assistants case
|
||||||
else if (ep === EModelEndpoint.assistants && assistants.length > 0) {
|
else if (ep === EModelEndpoint.assistants && assistants.length > 0) {
|
||||||
result.models = assistants.map((assistant: { id: string }) => assistant.id);
|
result.models = assistants.map((assistant: { id: string }) => ({
|
||||||
|
name: assistant.id,
|
||||||
|
isGlobal: false,
|
||||||
|
}));
|
||||||
result.assistantNames = assistants.reduce(
|
result.assistantNames = assistants.reduce(
|
||||||
(acc: Record<string, string>, assistant: Assistant) => {
|
(acc: Record<string, string>, assistant: Assistant) => {
|
||||||
acc[assistant.id] = assistant.name || '';
|
acc[assistant.id] = assistant.name || '';
|
||||||
|
|
@ -143,7 +152,10 @@ export const useEndpoints = ({
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
} else if (ep === EModelEndpoint.azureAssistants && azureAssistants.length > 0) {
|
} else if (ep === EModelEndpoint.azureAssistants && azureAssistants.length > 0) {
|
||||||
result.models = azureAssistants.map((assistant: { id: string }) => assistant.id);
|
result.models = azureAssistants.map((assistant: { id: string }) => ({
|
||||||
|
name: assistant.id,
|
||||||
|
isGlobal: false,
|
||||||
|
}));
|
||||||
result.assistantNames = azureAssistants.reduce(
|
result.assistantNames = azureAssistants.reduce(
|
||||||
(acc: Record<string, string>, assistant: Assistant) => {
|
(acc: Record<string, string>, assistant: Assistant) => {
|
||||||
acc[assistant.id] = assistant.name || '';
|
acc[assistant.id] = assistant.name || '';
|
||||||
|
|
@ -166,7 +178,10 @@ export const useEndpoints = ({
|
||||||
ep !== EModelEndpoint.assistants &&
|
ep !== EModelEndpoint.assistants &&
|
||||||
(modelsQuery.data?.[ep]?.length ?? 0) > 0
|
(modelsQuery.data?.[ep]?.length ?? 0) > 0
|
||||||
) {
|
) {
|
||||||
result.models = modelsQuery.data?.[ep];
|
result.models = modelsQuery.data?.[ep]?.map((model) => ({
|
||||||
|
name: model,
|
||||||
|
isGlobal: false,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
import { isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
|
||||||
import { ExtendedEndpoint } from '~/common';
|
|
||||||
|
|
||||||
export const filterMenuItems = (
|
|
||||||
searchTerm: string,
|
|
||||||
mappedEndpoints: ExtendedEndpoint[],
|
|
||||||
agents: any[],
|
|
||||||
assistants: any[],
|
|
||||||
modelsData: any,
|
|
||||||
): ExtendedEndpoint[] => {
|
|
||||||
if (!searchTerm.trim()) {
|
|
||||||
return mappedEndpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lowercaseSearchTerm = searchTerm.toLowerCase();
|
|
||||||
|
|
||||||
return mappedEndpoints
|
|
||||||
.map((ep) => {
|
|
||||||
if (ep.hasModels) {
|
|
||||||
if (isAgentsEndpoint(ep.value)) {
|
|
||||||
const filteredAgents = agents.filter((agent) =>
|
|
||||||
agent.name?.toLowerCase().includes(lowercaseSearchTerm),
|
|
||||||
);
|
|
||||||
if (ep.label.toLowerCase().includes(lowercaseSearchTerm) || filteredAgents.length > 0) {
|
|
||||||
return {
|
|
||||||
...ep,
|
|
||||||
models: filteredAgents.map((agent) => agent.id),
|
|
||||||
agentNames: filteredAgents.reduce((acc: Record<string, string>, agent) => {
|
|
||||||
acc[agent.id] = agent.name || '';
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} else if (isAssistantsEndpoint(ep.value)) {
|
|
||||||
const filteredAssistants = assistants.filter((assistant) =>
|
|
||||||
assistant.name?.toLowerCase().includes(lowercaseSearchTerm),
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
ep.label.toLowerCase().includes(lowercaseSearchTerm) ||
|
|
||||||
filteredAssistants.length > 0
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
...ep,
|
|
||||||
models: filteredAssistants.map((assistant) => assistant.id),
|
|
||||||
assistantNames: filteredAssistants.reduce(
|
|
||||||
(acc: Record<string, string>, assistant) => {
|
|
||||||
acc[assistant.id] = assistant.name || '';
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
const allModels = modelsData?.[ep.value] ?? [];
|
|
||||||
const filteredModels = allModels.filter((model: string) =>
|
|
||||||
model.toLowerCase().includes(lowercaseSearchTerm),
|
|
||||||
);
|
|
||||||
if (ep.label.toLowerCase().includes(lowercaseSearchTerm) || filteredModels.length > 0) {
|
|
||||||
return { ...ep, models: filteredModels };
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ep.label.toLowerCase().includes(lowercaseSearchTerm) ? { ...ep, models: [] } : null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean) as ExtendedEndpoint[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default filterMenuItems;
|
|
||||||
|
|
@ -20,7 +20,6 @@ export { default as logger } from './logger';
|
||||||
export { default as buildTree } from './buildTree';
|
export { default as buildTree } from './buildTree';
|
||||||
export { default as getLoginError } from './getLoginError';
|
export { default as getLoginError } from './getLoginError';
|
||||||
export { default as cleanupPreset } from './cleanupPreset';
|
export { default as cleanupPreset } from './cleanupPreset';
|
||||||
export { default as filterMenuItems } from './endpointFilter';
|
|
||||||
export { default as buildDefaultConvo } from './buildDefaultConvo';
|
export { default as buildDefaultConvo } from './buildDefaultConvo';
|
||||||
export { default as getDefaultEndpoint } from './getDefaultEndpoint';
|
export { default as getDefaultEndpoint } from './getDefaultEndpoint';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue