🥷 fix: Correct Agents Handling for Marketplace Users (#9065)

* refactor: Introduce ModelSelectorChatContext and integrate with ModelSelector

* fix: agents handling in ModelSelector to show expected agents if user has marketplace access
This commit is contained in:
Danny Avila 2025-08-14 19:13:48 -04:00 committed by GitHub
parent e4e25aaf2b
commit d57e7aec73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 124 additions and 57 deletions

View file

@ -9,7 +9,7 @@ export default function useAgentsMap({
}: {
isAuthenticated: boolean;
}): TAgentsMap | undefined {
const { data: agentsList = null } = useListAgentsQuery(
const { data: mappedAgents = null } = useListAgentsQuery(
{ requiredPermission: PermissionBits.VIEW },
{
select: (res) => mapAgents(res.data),
@ -17,9 +17,9 @@ export default function useAgentsMap({
},
);
const agents = useMemo<TAgentsMap | undefined>(() => {
return agentsList !== null ? agentsList : undefined;
}, [agentsList]);
const agentsMap = useMemo<TAgentsMap | undefined>(() => {
return mappedAgents !== null ? mappedAgents : undefined;
}, [mappedAgents]);
return agents;
return agentsMap;
}

View file

@ -1,71 +1,56 @@
import React, { useMemo, useCallback } from 'react';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import {
EModelEndpoint,
PermissionTypes,
Permissions,
alternateName,
EModelEndpoint,
PermissionTypes,
} from 'librechat-data-provider';
import type {
Agent,
Assistant,
TEndpointsConfig,
TAgentsMap,
TAssistantsMap,
TStartupConfig,
Assistant,
Agent,
} from 'librechat-data-provider';
import type { Endpoint } from '~/common';
import { mapEndpoints, getIconKey, getEndpointField } from '~/utils';
import { useGetEndpointsQuery } from '~/data-provider';
import { useChatContext } from '~/Providers';
import { useHasAccess } from '~/hooks';
import { icons } from './Icons';
export const useEndpoints = ({
agentsMap,
agents,
assistantsMap,
endpointsConfig,
startupConfig,
}: {
agentsMap?: TAgentsMap;
agents?: Agent[] | null;
assistantsMap?: TAssistantsMap;
endpointsConfig: TEndpointsConfig;
startupConfig: TStartupConfig | undefined;
}) => {
const modelsQuery = useGetModelsQuery();
const { conversation } = useChatContext();
const { data: endpoints = [] } = useGetEndpointsQuery({ select: mapEndpoints });
const { instanceProjectId } = startupConfig ?? {};
const interfaceConfig = startupConfig?.interface ?? {};
const includedEndpoints = useMemo(
() => new Set(startupConfig?.modelSpecs?.addedEndpoints ?? []),
[startupConfig?.modelSpecs?.addedEndpoints],
);
const { endpoint } = conversation ?? {};
const hasAgentAccess = useHasAccess({
permissionType: PermissionTypes.AGENTS,
permission: Permissions.USE,
});
const agents = useMemo(
() =>
Object.values(agentsMap ?? {}).filter(
(agent): agent is Agent & { name: string } =>
agent !== undefined && 'id' in agent && 'name' in agent && agent.name !== null,
),
[agentsMap],
);
const assistants: Assistant[] = useMemo(
() => Object.values(assistantsMap?.[EModelEndpoint.assistants] ?? {}),
[endpoint, assistantsMap],
[assistantsMap],
);
const azureAssistants: Assistant[] = useMemo(
() => Object.values(assistantsMap?.[EModelEndpoint.azureAssistants] ?? {}),
[endpoint, assistantsMap],
[assistantsMap],
);
const filteredEndpoints = useMemo(() => {
@ -84,7 +69,7 @@ export const useEndpoints = ({
}
return result;
}, [endpoints, hasAgentAccess, includedEndpoints]);
}, [endpoints, hasAgentAccess, includedEndpoints, interfaceConfig.modelSelect]);
const endpointRequiresUserKey = useCallback(
(ep: string) => {
@ -100,7 +85,7 @@ export const useEndpoints = ({
const Icon = icons[iconKey];
const endpointIconURL = getEndpointField(endpointsConfig, ep, 'iconURL');
const hasModels =
(ep === EModelEndpoint.agents && agents?.length > 0) ||
(ep === EModelEndpoint.agents && (agents?.length ?? 0) > 0) ||
(ep === EModelEndpoint.assistants && assistants?.length > 0) ||
(ep !== EModelEndpoint.assistants &&
ep !== EModelEndpoint.agents &&
@ -122,16 +107,16 @@ export const useEndpoints = ({
};
// Handle agents case
if (ep === EModelEndpoint.agents && agents.length > 0) {
result.models = agents.map((agent) => ({
if (ep === EModelEndpoint.agents && (agents?.length ?? 0) > 0) {
result.models = agents?.map((agent) => ({
name: agent.id,
isGlobal: agent.isPublic ?? false,
}));
result.agentNames = agents.reduce((acc, agent) => {
result.agentNames = agents?.reduce((acc, agent) => {
acc[agent.id] = agent.name || '';
return acc;
}, {});
result.modelIcons = agents.reduce((acc, agent) => {
result.modelIcons = agents?.reduce((acc, agent) => {
acc[agent.id] = agent?.avatar?.filepath;
return acc;
}, {});
@ -192,7 +177,7 @@ export const useEndpoints = ({
return result;
});
}, [filteredEndpoints, endpointsConfig, modelsQuery.data, agents, assistants]);
}, [filteredEndpoints, endpointsConfig, modelsQuery.data, agents, assistants, azureAssistants]);
return {
mappedEndpoints,