mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 10:20:15 +01:00
🔧 fix: Merge and Rebase Conflicts
- Move AgentCategory from api/models to @packages/data-schemas structure - Add schema, types, methods, and model following codebase conventions - Implement auto-seeding of default categories during AppService startup - Update marketplace controller to use new data-schemas methods - Remove old model file and standalone seed script 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 feat: add icon property to ProcessedAgentCategory interface - Add useMarketplaceAgentsInfiniteQuery and useGetAgentCategoriesQuery to client/src/data-provider/Agents/ - Replace manual pagination in AgentGrid with infinite query pattern - Update imports to use local data provider instead of librechat-data-provider - Add proper permission handling with PERMISSION_BITS.VIEW/EDIT constants - Improve agent access control by adding requiredPermission validation in backend - Remove manual cursor/state management in favor of infinite query built-ins - Maintain existing search and category filtering functionality refactor: consolidate agent marketplace endpoints into main agents API and improve data management consistency - Remove dedicated marketplace controller and routes, merging functionality into main agents v1 API - Add countPromotedAgents function to Agent model for promoted agents count - Enhance getListAgents handler with marketplace filtering (category, search, promoted status) - Move getAgentCategories from marketplace to v1 controller with same functionality - Update agent mutations to invalidate marketplace queries and handle multiple permission levels - Improve cache management by updating all agent query variants (VIEW/EDIT permissions) - Consolidate agent data access patterns for better maintainability and consistency - Remove duplicate marketplace route definitions and middleware selected view only agents injected in the drop down fix: remove minlength validation for support contact name in agent schema feat: add validation and error messages for agent name in AgentConfig and AgentPanel fix: update agent permission check logic in AgentPanel to simplify condition Fix linting WIP Fix Unit tests WIP ESLint fixes eslint fix refactor: enhance isDuplicateVersion function in Agent model for improved comparison logic - Introduced handling for undefined/null values in array and object comparisons. - Normalized array comparisons to treat undefined/null as empty arrays. - Added deep comparison for objects and improved handling of primitive values. - Enhanced projectIds comparison to ensure consistent MongoDB ObjectId handling. refactor: remove redundant properties from IAgent interface in agent schema chore: update localization for agent detail component and clean up imports ci: update access middleware tests chore: remove unused PermissionTypes import from Role model ci: update AclEntry model tests ci: update button accessibility labels in AgentDetail tests refactor: update exhaustive dep. lint warning
This commit is contained in:
parent
9e2243e688
commit
27da0c6d9f
60 changed files with 1524 additions and 2004 deletions
|
|
@ -17,6 +17,8 @@ const {
|
|||
updateAgent,
|
||||
deleteAgent,
|
||||
getListAgentsByAccess,
|
||||
countPromotedAgents,
|
||||
revertAgentVersion,
|
||||
} = require('~/models/Agent');
|
||||
const {
|
||||
grantPermission,
|
||||
|
|
@ -30,8 +32,8 @@ const { refreshS3Url } = require('~/server/services/Files/S3/crud');
|
|||
const { filterFile } = require('~/server/services/Files/process');
|
||||
const { updateAction, getActions } = require('~/models/Action');
|
||||
const { getCachedTools } = require('~/server/services/Config');
|
||||
const { revertAgentVersion } = require('~/models/Agent');
|
||||
const { deleteFileByFilter } = require('~/models/File');
|
||||
const { getCategoriesWithCounts } = require('~/models');
|
||||
|
||||
const systemTools = {
|
||||
[Tools.execute_code]: true,
|
||||
|
|
@ -399,12 +401,43 @@ const deleteAgentHandler = async (req, res) => {
|
|||
const getListAgentsHandler = async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const { category, search, limit, cursor, promoted } = req.query;
|
||||
let requiredPermission = req.query.requiredPermission;
|
||||
if (typeof requiredPermission === 'string') {
|
||||
requiredPermission = parseInt(requiredPermission, 10);
|
||||
if (isNaN(requiredPermission)) {
|
||||
requiredPermission = PermissionBits.VIEW;
|
||||
}
|
||||
} else if (typeof requiredPermission !== 'number') {
|
||||
requiredPermission = PermissionBits.VIEW;
|
||||
}
|
||||
// Base filter
|
||||
const filter = {};
|
||||
|
||||
// Handle category filter - only apply if category is defined
|
||||
if (category !== undefined && category.trim() !== '') {
|
||||
filter.category = category;
|
||||
}
|
||||
|
||||
// Handle promoted filter - only from query param
|
||||
if (promoted === '1') {
|
||||
filter.is_promoted = true;
|
||||
} else if (promoted === '0') {
|
||||
filter.is_promoted = { $ne: true };
|
||||
}
|
||||
|
||||
// Handle search filter
|
||||
if (search && search.trim() !== '') {
|
||||
filter.$or = [
|
||||
{ name: { $regex: search.trim(), $options: 'i' } },
|
||||
{ description: { $regex: search.trim(), $options: 'i' } },
|
||||
];
|
||||
}
|
||||
// Get agent IDs the user has VIEW access to via ACL
|
||||
const accessibleIds = await findAccessibleResources({
|
||||
userId,
|
||||
resourceType: 'agent',
|
||||
requiredPermissions: PermissionBits.VIEW,
|
||||
requiredPermissions: requiredPermission,
|
||||
});
|
||||
const publiclyAccessibleIds = await findPubliclyAccessibleResources({
|
||||
resourceType: 'agent',
|
||||
|
|
@ -413,7 +446,9 @@ const getListAgentsHandler = async (req, res) => {
|
|||
// Use the new ACL-aware function
|
||||
const data = await getListAgentsByAccess({
|
||||
accessibleIds,
|
||||
otherParams: {}, // Can add query params here if needed
|
||||
otherParams: filter,
|
||||
limit,
|
||||
after: cursor,
|
||||
});
|
||||
if (data?.data?.length) {
|
||||
data.data = data.data.map((agent) => {
|
||||
|
|
@ -589,7 +624,48 @@ const revertAgentVersionHandler = async (req, res) => {
|
|||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Get all agent categories with counts
|
||||
*
|
||||
* @param {Object} _req - Express request object (unused)
|
||||
* @param {Object} res - Express response object
|
||||
*/
|
||||
const getAgentCategories = async (_req, res) => {
|
||||
try {
|
||||
const categories = await getCategoriesWithCounts();
|
||||
const promotedCount = await countPromotedAgents();
|
||||
const formattedCategories = categories.map((category) => ({
|
||||
value: category.value,
|
||||
label: category.label,
|
||||
count: category.agentCount,
|
||||
description: category.description,
|
||||
}));
|
||||
|
||||
if (promotedCount > 0) {
|
||||
formattedCategories.unshift({
|
||||
value: 'promoted',
|
||||
label: 'Promoted',
|
||||
count: promotedCount,
|
||||
description: 'Our recommended agents',
|
||||
});
|
||||
}
|
||||
|
||||
formattedCategories.push({
|
||||
value: 'all',
|
||||
label: 'All',
|
||||
description: 'All available agents',
|
||||
});
|
||||
|
||||
res.status(200).json(formattedCategories);
|
||||
} catch (error) {
|
||||
logger.error('[/Agents/Marketplace] Error fetching agent categories:', error);
|
||||
res.status(500).json({
|
||||
error: 'Failed to fetch agent categories',
|
||||
userMessage: 'Unable to load categories. Please refresh the page.',
|
||||
suggestion: 'Try refreshing the page or check your network connection',
|
||||
});
|
||||
}
|
||||
};
|
||||
module.exports = {
|
||||
createAgent: createAgentHandler,
|
||||
getAgent: getAgentHandler,
|
||||
|
|
@ -599,4 +675,5 @@ module.exports = {
|
|||
getListAgents: getListAgentsHandler,
|
||||
uploadAgentAvatar: uploadAgentAvatarHandler,
|
||||
revertAgentVersion: revertAgentVersionHandler,
|
||||
getAgentCategories,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue