mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-28 21:30:18 +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
|
|
@ -271,22 +271,7 @@ describe('AclEntry Model Tests', () => {
|
|||
const effective = await methods.getEffectivePermissions(principalsList, 'agent', resourceId);
|
||||
|
||||
/** Combined permissions should be VIEW | EDIT */
|
||||
expect(effective.effectiveBits).toBe(PermissionBits.VIEW | PermissionBits.EDIT);
|
||||
|
||||
/** Should have 2 sources */
|
||||
expect(effective.sources).toHaveLength(2);
|
||||
|
||||
/** Check sources */
|
||||
const userSource = effective.sources.find((s) => s.from === 'user');
|
||||
const groupSource = effective.sources.find((s) => s.from === 'group');
|
||||
|
||||
expect(userSource).toBeDefined();
|
||||
expect(userSource?.permBits).toBe(PermissionBits.VIEW);
|
||||
expect(userSource?.direct).toBe(true);
|
||||
|
||||
expect(groupSource).toBeDefined();
|
||||
expect(groupSource?.permBits).toBe(PermissionBits.EDIT);
|
||||
expect(groupSource?.direct).toBe(true);
|
||||
expect(effective).toBe(PermissionBits.VIEW | PermissionBits.EDIT);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -489,16 +474,15 @@ describe('AclEntry Model Tests', () => {
|
|||
inheritedFrom: projectId,
|
||||
});
|
||||
|
||||
/** Get effective permissions including sources */
|
||||
/** Get effective permissions */
|
||||
const effective = await methods.getEffectivePermissions(
|
||||
[{ principalType: 'user', principalId: userId }],
|
||||
'agent',
|
||||
childResourceId,
|
||||
);
|
||||
|
||||
expect(effective.sources).toHaveLength(1);
|
||||
expect(effective.sources[0].inheritedFrom?.toString()).toBe(projectId.toString());
|
||||
expect(effective.sources[0].direct).toBe(false);
|
||||
/** Should have VIEW permission from inherited entry */
|
||||
expect(effective).toBe(PermissionBits.VIEW);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -144,6 +144,66 @@ export function createAgentCategoryMethods(mongoose: typeof import('mongoose'))
|
|||
return await AgentCategory.find({}).sort({ order: 1, label: 1 }).lean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure default categories exist, seed them if none are present
|
||||
* @returns Promise<boolean> - true if categories were seeded, false if they already existed
|
||||
*/
|
||||
async function ensureDefaultCategories(): Promise<boolean> {
|
||||
const existingCategories = await getAllCategories();
|
||||
|
||||
if (existingCategories.length > 0) {
|
||||
return false; // Categories already exist
|
||||
}
|
||||
|
||||
const defaultCategories = [
|
||||
{
|
||||
value: 'general',
|
||||
label: 'General',
|
||||
description: 'General purpose agents for common tasks and inquiries',
|
||||
order: 0,
|
||||
},
|
||||
{
|
||||
value: 'hr',
|
||||
label: 'Human Resources',
|
||||
description: 'Agents specialized in HR processes, policies, and employee support',
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
value: 'rd',
|
||||
label: 'Research & Development',
|
||||
description: 'Agents focused on R&D processes, innovation, and technical research',
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
value: 'finance',
|
||||
label: 'Finance',
|
||||
description: 'Agents specialized in financial analysis, budgeting, and accounting',
|
||||
order: 3,
|
||||
},
|
||||
{
|
||||
value: 'it',
|
||||
label: 'IT',
|
||||
description: 'Agents for IT support, technical troubleshooting, and system administration',
|
||||
order: 4,
|
||||
},
|
||||
{
|
||||
value: 'sales',
|
||||
label: 'Sales',
|
||||
description: 'Agents focused on sales processes, customer relations.',
|
||||
order: 5,
|
||||
},
|
||||
{
|
||||
value: 'aftersales',
|
||||
label: 'After Sales',
|
||||
description: 'Agents specialized in post-sale support, maintenance, and customer service',
|
||||
order: 6,
|
||||
},
|
||||
];
|
||||
|
||||
await seedCategories(defaultCategories);
|
||||
return true; // Categories were seeded
|
||||
}
|
||||
|
||||
return {
|
||||
getActiveCategories,
|
||||
getCategoriesWithCounts,
|
||||
|
|
@ -155,6 +215,7 @@ export function createAgentCategoryMethods(mongoose: typeof import('mongoose'))
|
|||
deleteCategory,
|
||||
findCategoryById,
|
||||
getAllCategories,
|
||||
ensureDefaultCategories,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
9
packages/data-schemas/src/models/agentCategory.ts
Normal file
9
packages/data-schemas/src/models/agentCategory.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import agentCategorySchema from '~/schema/agentCategory';
|
||||
import type * as t from '~/types';
|
||||
|
||||
/**
|
||||
* Creates or returns the AgentCategory model using the provided mongoose instance and schema
|
||||
*/
|
||||
export function createAgentCategoryModel(mongoose: typeof import('mongoose')) {
|
||||
return mongoose.models.AgentCategory || mongoose.model<t.IAgentCategory>('AgentCategory', agentCategorySchema);
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import { createBalanceModel } from './balance';
|
|||
import { createConversationModel } from './convo';
|
||||
import { createMessageModel } from './message';
|
||||
import { createAgentModel } from './agent';
|
||||
import { createAgentCategoryModel } from './agentCategory';
|
||||
import { createRoleModel } from './role';
|
||||
import { createActionModel } from './action';
|
||||
import { createAssistantModel } from './assistant';
|
||||
|
|
@ -37,6 +38,7 @@ export function createModels(mongoose: typeof import('mongoose')) {
|
|||
Conversation: createConversationModel(mongoose),
|
||||
Message: createMessageModel(mongoose),
|
||||
Agent: createAgentModel(mongoose),
|
||||
AgentCategory: createAgentCategoryModel(mongoose),
|
||||
Role: createRoleModel(mongoose),
|
||||
Action: createActionModel(mongoose),
|
||||
Assistant: createAssistantModel(mongoose),
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ const agentSchema = new Schema<IAgent>(
|
|||
type: {
|
||||
name: {
|
||||
type: String,
|
||||
minlength: [3, 'Support contact name must be at least 3 characters.'],
|
||||
trim: true,
|
||||
},
|
||||
email: {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
import { Schema, Document } from 'mongoose';
|
||||
|
||||
export interface IAgentCategory extends Document {
|
||||
value: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
order: number;
|
||||
isActive: boolean;
|
||||
}
|
||||
import type { IAgentCategory } from '~/types';
|
||||
|
||||
const agentCategorySchema = new Schema<IAgentCategory>(
|
||||
{
|
||||
|
|
@ -46,4 +39,4 @@ const agentCategorySchema = new Schema<IAgentCategory>(
|
|||
|
||||
agentCategorySchema.index({ isActive: 1, order: 1 });
|
||||
|
||||
export default agentCategorySchema;
|
||||
export default agentCategorySchema;
|
||||
|
|
|
|||
|
|
@ -36,10 +36,5 @@ export interface IAgent extends Omit<Document, 'model'> {
|
|||
versions?: Omit<IAgent, 'versions'>[];
|
||||
category: string;
|
||||
support_contact?: ISupportContact;
|
||||
category: string;
|
||||
support_contact?: {
|
||||
name?: string;
|
||||
email?: string;
|
||||
};
|
||||
is_promoted?: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export * from './balance';
|
|||
export * from './banner';
|
||||
export * from './message';
|
||||
export * from './agent';
|
||||
export * from './agentCategory';
|
||||
export * from './role';
|
||||
export * from './action';
|
||||
export * from './assistant';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue