const mongoose = require('mongoose'); const { ResourceType, PermissionBits, PrincipalType, PrincipalModel, } = require('librechat-data-provider'); const { MongoMemoryServer } = require('mongodb-memory-server'); const mockInitializeAgent = jest.fn(); const mockValidateAgentModel = jest.fn(); jest.mock('@librechat/agents', () => ({ ...jest.requireActual('@librechat/agents'), createContentAggregator: jest.fn(() => ({ contentParts: [], aggregateContent: jest.fn(), })), })); jest.mock('@librechat/api', () => ({ ...jest.requireActual('@librechat/api'), initializeAgent: (...args) => mockInitializeAgent(...args), validateAgentModel: (...args) => mockValidateAgentModel(...args), GenerationJobManager: { setCollectedUsage: jest.fn() }, getCustomEndpointConfig: jest.fn(), createSequentialChainEdges: jest.fn(), })); jest.mock('~/server/controllers/agents/callbacks', () => ({ createToolEndCallback: jest.fn(() => jest.fn()), getDefaultHandlers: jest.fn(() => ({})), })); jest.mock('~/server/services/ToolService', () => ({ loadAgentTools: jest.fn(), loadToolsForExecution: jest.fn(), })); jest.mock('~/server/controllers/ModelController', () => ({ getModelsConfig: jest.fn().mockResolvedValue({}), })); let agentClientArgs; jest.mock('~/server/controllers/agents/client', () => { return jest.fn().mockImplementation((args) => { agentClientArgs = args; return {}; }); }); jest.mock('./addedConvo', () => ({ processAddedConvo: jest.fn().mockResolvedValue({ userMCPAuthMap: undefined }), })); jest.mock('~/cache', () => ({ logViolation: jest.fn(), })); const { initializeClient } = require('./initialize'); const { createAgent } = require('~/models/Agent'); const { User, AclEntry } = require('~/db/models'); const PRIMARY_ID = 'agent_primary'; const TARGET_ID = 'agent_target'; const AUTHORIZED_ID = 'agent_authorized'; describe('initializeClient — processAgent ACL gate', () => { let mongoServer; let testUser; beforeAll(async () => { mongoServer = await MongoMemoryServer.create(); await mongoose.connect(mongoServer.getUri()); }); afterAll(async () => { await mongoose.disconnect(); await mongoServer.stop(); }); beforeEach(async () => { await mongoose.connection.dropDatabase(); jest.clearAllMocks(); agentClientArgs = undefined; testUser = await User.create({ email: 'test@example.com', name: 'Test User', username: 'testuser', role: 'USER', }); mockValidateAgentModel.mockResolvedValue({ isValid: true }); }); const makeReq = () => ({ user: { id: testUser._id.toString(), role: 'USER' }, body: { conversationId: 'conv_1', files: [] }, config: { endpoints: {} }, _resumableStreamId: null, }); const makeEndpointOption = () => ({ agent: Promise.resolve({ id: PRIMARY_ID, name: 'Primary', provider: 'openai', model: 'gpt-4', tools: [], }), model_parameters: { model: 'gpt-4' }, endpoint: 'agents', }); const makePrimaryConfig = (edges) => ({ id: PRIMARY_ID, endpoint: 'agents', edges, toolDefinitions: [], toolRegistry: new Map(), userMCPAuthMap: null, tool_resources: {}, resendFiles: true, maxContextTokens: 4096, }); it('should skip handoff agent and filter its edge when user lacks VIEW access', async () => { await createAgent({ id: TARGET_ID, name: 'Target Agent', provider: 'openai', model: 'gpt-4', author: new mongoose.Types.ObjectId(), tools: [], }); const edges = [{ from: PRIMARY_ID, to: TARGET_ID, edgeType: 'handoff' }]; mockInitializeAgent.mockResolvedValue(makePrimaryConfig(edges)); await initializeClient({ req: makeReq(), res: {}, signal: new AbortController().signal, endpointOption: makeEndpointOption(), }); expect(mockInitializeAgent).toHaveBeenCalledTimes(1); expect(agentClientArgs.agent.edges).toEqual([]); }); it('should initialize handoff agent and keep its edge when user has VIEW access', async () => { const authorizedAgent = await createAgent({ id: AUTHORIZED_ID, name: 'Authorized Agent', provider: 'openai', model: 'gpt-4', author: new mongoose.Types.ObjectId(), tools: [], }); await AclEntry.create({ principalType: PrincipalType.USER, principalId: testUser._id, principalModel: PrincipalModel.USER, resourceType: ResourceType.AGENT, resourceId: authorizedAgent._id, permBits: PermissionBits.VIEW, grantedBy: testUser._id, }); const edges = [{ from: PRIMARY_ID, to: AUTHORIZED_ID, edgeType: 'handoff' }]; const handoffConfig = { id: AUTHORIZED_ID, edges: [], toolDefinitions: [], toolRegistry: new Map(), userMCPAuthMap: null, tool_resources: {}, }; let callCount = 0; mockInitializeAgent.mockImplementation(() => { callCount++; return callCount === 1 ? Promise.resolve(makePrimaryConfig(edges)) : Promise.resolve(handoffConfig); }); await initializeClient({ req: makeReq(), res: {}, signal: new AbortController().signal, endpointOption: makeEndpointOption(), }); expect(mockInitializeAgent).toHaveBeenCalledTimes(2); expect(agentClientArgs.agent.edges).toHaveLength(1); expect(agentClientArgs.agent.edges[0].to).toBe(AUTHORIZED_ID); }); });