mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-27 20:56:12 +01:00
🧩 fix: Missing Memory Agent Assignment for Matching IDs (#11514)
Some checks failed
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been cancelled
Some checks failed
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Has been cancelled
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Has been cancelled
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been cancelled
* fix: `useMemory` in AgentClient for PrelimAgent Assignment * Updated the useMemory method in AgentClient to handle prelimAgent assignment based on memory configuration. * Added logic to return early if prelimAgent is undefined, improving flow control. * Introduced comprehensive unit tests to validate behavior for various memory configurations, including scenarios for matching and differing agent IDs, as well as handling of ephemeral agents. * Mocked necessary dependencies in tests to ensure isolation and reliability of the new functionality. * fix: Update temperature handling for Bedrock and Anthropic providers in memory management * fix: Replace hardcoded provider strings with constants in memory agent tests * fix: Replace hardcoded provider string with constant in allowedProviders for AgentClient * fix: memory agent tests to use actual Providers and GraphEvents constants
This commit is contained in:
parent
6a49861861
commit
0b4deac953
4 changed files with 378 additions and 20 deletions
|
|
@ -12,6 +12,17 @@ jest.mock('@librechat/agents', () => ({
|
|||
|
||||
jest.mock('@librechat/api', () => ({
|
||||
...jest.requireActual('@librechat/api'),
|
||||
checkAccess: jest.fn(),
|
||||
initializeAgent: jest.fn(),
|
||||
createMemoryProcessor: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/models/Agent', () => ({
|
||||
loadAgent: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/models/Role', () => ({
|
||||
getRoleByName: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock getMCPManager
|
||||
|
|
@ -2070,4 +2081,179 @@ describe('AgentClient - titleConvo', () => {
|
|||
expect(client.options.agent.instructions).toContain(memoryContent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useMemory method - prelimAgent assignment', () => {
|
||||
let client;
|
||||
let mockReq;
|
||||
let mockRes;
|
||||
let mockAgent;
|
||||
let mockOptions;
|
||||
let mockCheckAccess;
|
||||
let mockLoadAgent;
|
||||
let mockInitializeAgent;
|
||||
let mockCreateMemoryProcessor;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockAgent = {
|
||||
id: 'agent-123',
|
||||
endpoint: EModelEndpoint.openAI,
|
||||
provider: EModelEndpoint.openAI,
|
||||
instructions: 'Test instructions',
|
||||
model: 'gpt-4',
|
||||
model_parameters: {
|
||||
model: 'gpt-4',
|
||||
},
|
||||
};
|
||||
|
||||
mockReq = {
|
||||
user: {
|
||||
id: 'user-123',
|
||||
personalization: {
|
||||
memories: true,
|
||||
},
|
||||
},
|
||||
config: {
|
||||
memory: {
|
||||
agent: {
|
||||
id: 'agent-123',
|
||||
},
|
||||
},
|
||||
endpoints: {
|
||||
[EModelEndpoint.agents]: {
|
||||
allowedProviders: [EModelEndpoint.openAI],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
mockRes = {};
|
||||
|
||||
mockOptions = {
|
||||
req: mockReq,
|
||||
res: mockRes,
|
||||
agent: mockAgent,
|
||||
};
|
||||
|
||||
mockCheckAccess = require('@librechat/api').checkAccess;
|
||||
mockLoadAgent = require('~/models/Agent').loadAgent;
|
||||
mockInitializeAgent = require('@librechat/api').initializeAgent;
|
||||
mockCreateMemoryProcessor = require('@librechat/api').createMemoryProcessor;
|
||||
});
|
||||
|
||||
it('should use current agent when memory config agent.id matches current agent id', async () => {
|
||||
mockCheckAccess.mockResolvedValue(true);
|
||||
mockInitializeAgent.mockResolvedValue({
|
||||
...mockAgent,
|
||||
provider: EModelEndpoint.openAI,
|
||||
});
|
||||
mockCreateMemoryProcessor.mockResolvedValue([undefined, jest.fn()]);
|
||||
|
||||
client = new AgentClient(mockOptions);
|
||||
client.conversationId = 'convo-123';
|
||||
client.responseMessageId = 'response-123';
|
||||
|
||||
await client.useMemory();
|
||||
|
||||
expect(mockLoadAgent).not.toHaveBeenCalled();
|
||||
expect(mockInitializeAgent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agent: mockAgent,
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it('should load different agent when memory config agent.id differs from current agent id', async () => {
|
||||
const differentAgentId = 'different-agent-456';
|
||||
const differentAgent = {
|
||||
id: differentAgentId,
|
||||
provider: EModelEndpoint.openAI,
|
||||
model: 'gpt-4',
|
||||
instructions: 'Different agent instructions',
|
||||
};
|
||||
|
||||
mockReq.config.memory.agent.id = differentAgentId;
|
||||
|
||||
mockCheckAccess.mockResolvedValue(true);
|
||||
mockLoadAgent.mockResolvedValue(differentAgent);
|
||||
mockInitializeAgent.mockResolvedValue({
|
||||
...differentAgent,
|
||||
provider: EModelEndpoint.openAI,
|
||||
});
|
||||
mockCreateMemoryProcessor.mockResolvedValue([undefined, jest.fn()]);
|
||||
|
||||
client = new AgentClient(mockOptions);
|
||||
client.conversationId = 'convo-123';
|
||||
client.responseMessageId = 'response-123';
|
||||
|
||||
await client.useMemory();
|
||||
|
||||
expect(mockLoadAgent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agent_id: differentAgentId,
|
||||
}),
|
||||
);
|
||||
expect(mockInitializeAgent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agent: differentAgent,
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it('should return early when prelimAgent is undefined (no valid memory agent config)', async () => {
|
||||
mockReq.config.memory = {
|
||||
agent: {},
|
||||
};
|
||||
|
||||
mockCheckAccess.mockResolvedValue(true);
|
||||
|
||||
client = new AgentClient(mockOptions);
|
||||
client.conversationId = 'convo-123';
|
||||
client.responseMessageId = 'response-123';
|
||||
|
||||
const result = await client.useMemory();
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
expect(mockInitializeAgent).not.toHaveBeenCalled();
|
||||
expect(mockCreateMemoryProcessor).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should create ephemeral agent when no id but model and provider are specified', async () => {
|
||||
mockReq.config.memory = {
|
||||
agent: {
|
||||
model: 'gpt-4',
|
||||
provider: EModelEndpoint.openAI,
|
||||
},
|
||||
};
|
||||
|
||||
mockCheckAccess.mockResolvedValue(true);
|
||||
mockInitializeAgent.mockResolvedValue({
|
||||
id: Constants.EPHEMERAL_AGENT_ID,
|
||||
model: 'gpt-4',
|
||||
provider: EModelEndpoint.openAI,
|
||||
});
|
||||
mockCreateMemoryProcessor.mockResolvedValue([undefined, jest.fn()]);
|
||||
|
||||
client = new AgentClient(mockOptions);
|
||||
client.conversationId = 'convo-123';
|
||||
client.responseMessageId = 'response-123';
|
||||
|
||||
await client.useMemory();
|
||||
|
||||
expect(mockLoadAgent).not.toHaveBeenCalled();
|
||||
expect(mockInitializeAgent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agent: expect.objectContaining({
|
||||
id: Constants.EPHEMERAL_AGENT_ID,
|
||||
model: 'gpt-4',
|
||||
provider: EModelEndpoint.openAI,
|
||||
}),
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue