mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-29 22:05:18 +01:00
refactor: unify agent marketplace to single endpoint with cursor pagination
- Replace multiple marketplace routes with unified /marketplace endpoint - Add query string controls: category, search, limit, cursor, promoted, requiredPermission - Implement cursor-based pagination replacing page-based system - Integrate ACL permissions for proper access control - Fix ObjectId constructor error in Agent model - Update React components to use unified useGetMarketplaceAgentsQuery hook - Enhance type safety and remove deprecated useDynamicAgentQuery - Update tests for new marketplace architecture -Known issues: see more button after category switching + Unit tests
This commit is contained in:
parent
be7476d530
commit
2eef94d58d
22 changed files with 458 additions and 1128 deletions
|
|
@ -455,65 +455,19 @@ export const getAgentCategories = (): Promise<t.TMarketplaceCategory[]> => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get promoted/top picks agents with pagination
|
||||
* Unified marketplace agents endpoint with query string controls
|
||||
*/
|
||||
export const getPromotedAgents = (params: {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
showAll?: string; // Add showAll parameter to get all shared agents instead of just promoted
|
||||
}): Promise<a.AgentListResponse> => {
|
||||
return request.get(
|
||||
endpoints.agents({
|
||||
path: 'marketplace/promoted',
|
||||
options: params,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all agents with pagination (for "all" category)
|
||||
*/
|
||||
export const getAllAgents = (params: {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}): Promise<a.AgentListResponse> => {
|
||||
return request.get(
|
||||
endpoints.agents({
|
||||
path: 'marketplace/all',
|
||||
options: params,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get agents by category with pagination
|
||||
*/
|
||||
export const getAgentsByCategory = (params: {
|
||||
category: string;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}): Promise<a.AgentListResponse> => {
|
||||
const { category, ...options } = params;
|
||||
return request.get(
|
||||
endpoints.agents({
|
||||
path: `marketplace/category/${category}`,
|
||||
options,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Search agents in marketplace
|
||||
*/
|
||||
export const searchAgents = (params: {
|
||||
q: string;
|
||||
export const getMarketplaceAgents = (params: {
|
||||
requiredPermission: number;
|
||||
category?: string;
|
||||
page?: number;
|
||||
search?: string;
|
||||
limit?: number;
|
||||
cursor?: string;
|
||||
promoted?: 0 | 1;
|
||||
}): Promise<a.AgentListResponse> => {
|
||||
return request.get(
|
||||
endpoints.agents({
|
||||
path: 'marketplace/search',
|
||||
path: 'marketplace',
|
||||
options: params,
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ import * as dataService from './data-service';
|
|||
export * from './utils';
|
||||
export * from './actions';
|
||||
export { default as createPayload } from './createPayload';
|
||||
// /* react query hooks */
|
||||
// export * from './react-query/react-query-service';
|
||||
/* feedback */
|
||||
export * from './feedback';
|
||||
export * from './parameterSettings';
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ export enum QueryKeys {
|
|||
promptGroup = 'promptGroup',
|
||||
categories = 'categories',
|
||||
randomPrompts = 'randomPrompts',
|
||||
agentCategories = 'agentCategories',
|
||||
marketplaceAgents = 'marketplaceAgents',
|
||||
roles = 'roles',
|
||||
conversationTags = 'conversationTags',
|
||||
health = 'health',
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import * as q from '../types/queries';
|
|||
import { QueryKeys } from '../keys';
|
||||
import * as s from '../schemas';
|
||||
import * as t from '../types';
|
||||
import * as a from '../types/assistants';
|
||||
import * as permissions from '../accessPermissions';
|
||||
|
||||
export { hasPermissions } from '../accessPermissions';
|
||||
|
|
@ -450,3 +451,52 @@ export const useGetEffectivePermissionsQuery = (
|
|||
...config,
|
||||
});
|
||||
};
|
||||
|
||||
/* Marketplace */
|
||||
|
||||
/**
|
||||
* Get agent categories with counts for marketplace tabs
|
||||
*/
|
||||
export const useGetAgentCategoriesQuery = (
|
||||
config?: UseQueryOptions<t.TMarketplaceCategory[]>,
|
||||
): QueryObserverResult<t.TMarketplaceCategory[]> => {
|
||||
return useQuery<t.TMarketplaceCategory[]>(
|
||||
[QueryKeys.agentCategories],
|
||||
() => dataService.getAgentCategories(),
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
|
||||
...config,
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Unified marketplace agents query with query string controls
|
||||
*/
|
||||
export const useGetMarketplaceAgentsQuery = (
|
||||
params: {
|
||||
requiredPermission: number;
|
||||
category?: string;
|
||||
search?: string;
|
||||
limit?: number;
|
||||
cursor?: string;
|
||||
promoted?: 0 | 1;
|
||||
},
|
||||
config?: UseQueryOptions<a.AgentListResponse>,
|
||||
): QueryObserverResult<a.AgentListResponse> => {
|
||||
return useQuery<a.AgentListResponse>(
|
||||
[QueryKeys.marketplaceAgents, params],
|
||||
() => dataService.getMarketplaceAgents(params),
|
||||
{
|
||||
enabled: !!params.requiredPermission,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
staleTime: 2 * 60 * 1000, // Cache for 2 minutes
|
||||
...config,
|
||||
},
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ export interface AgentFileResource extends AgentBaseResource {
|
|||
*/
|
||||
vector_store_ids?: Array<string>;
|
||||
}
|
||||
export type SupportContact = {
|
||||
name?: string;
|
||||
email?: string;
|
||||
};
|
||||
|
||||
export type Agent = {
|
||||
_id?: string;
|
||||
|
|
@ -228,6 +232,8 @@ export type Agent = {
|
|||
recursion_limit?: number;
|
||||
isPublic?: boolean;
|
||||
version?: number;
|
||||
category?: string;
|
||||
support_contact?: SupportContact;
|
||||
};
|
||||
|
||||
export type TAgentsMap = Record<string, Agent | undefined>;
|
||||
|
|
@ -244,7 +250,13 @@ export type AgentCreateParams = {
|
|||
model_parameters: AgentModelParameters;
|
||||
} & Pick<
|
||||
Agent,
|
||||
'agent_ids' | 'end_after_tools' | 'hide_sequential_outputs' | 'artifacts' | 'recursion_limit'
|
||||
| 'agent_ids'
|
||||
| 'end_after_tools'
|
||||
| 'hide_sequential_outputs'
|
||||
| 'artifacts'
|
||||
| 'recursion_limit'
|
||||
| 'category'
|
||||
| 'support_contact'
|
||||
>;
|
||||
|
||||
export type AgentUpdateParams = {
|
||||
|
|
@ -263,7 +275,13 @@ export type AgentUpdateParams = {
|
|||
isCollaborative?: boolean;
|
||||
} & Pick<
|
||||
Agent,
|
||||
'agent_ids' | 'end_after_tools' | 'hide_sequential_outputs' | 'artifacts' | 'recursion_limit'
|
||||
| 'agent_ids'
|
||||
| 'end_after_tools'
|
||||
| 'hide_sequential_outputs'
|
||||
| 'artifacts'
|
||||
| 'recursion_limit'
|
||||
| 'category'
|
||||
| 'support_contact'
|
||||
>;
|
||||
|
||||
export type AgentListParams = {
|
||||
|
|
@ -272,6 +290,7 @@ export type AgentListParams = {
|
|||
after?: string | null;
|
||||
order?: 'asc' | 'desc';
|
||||
provider?: AgentProvider;
|
||||
requiredPermission?: number;
|
||||
};
|
||||
|
||||
export type AgentListResponse = {
|
||||
|
|
@ -280,6 +299,7 @@ export type AgentListResponse = {
|
|||
first_id: string;
|
||||
last_id: string;
|
||||
has_more: boolean;
|
||||
after?: string;
|
||||
};
|
||||
|
||||
export type AgentFile = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue