mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-07-10 00:03:03 +00:00
🧠 fix: Persist memory capability on saved agents; honor registration flag
- Add Tools.memory to the v1 systemTools allowlist so filterAuthorizedTools no longer silently drops the memory marker when an agent with the Memory capability is created/updated/duplicated through the builder (previously the capability only worked for ephemeral chats, not persisted agents). - agentHasInlineMemoryTools now honors an explicit memoryToolsRegistered boolean before falling back to the raw `memory` marker, so an initialized config whose registration was denied (memoryAvailable false) is not given keyed memory context just because the marker survives in tools.
This commit is contained in:
parent
4754c981aa
commit
b5362e9b28
4 changed files with 34 additions and 4 deletions
|
|
@ -183,12 +183,12 @@ describe('MCP Tool Authorization', () => {
|
|||
|
||||
test('should keep system tools without querying MCP registry', async () => {
|
||||
const result = await filterAuthorizedTools({
|
||||
tools: ['execute_code', 'file_search', 'web_search'],
|
||||
tools: ['execute_code', 'file_search', 'web_search', 'memory'],
|
||||
userId,
|
||||
availableTools: {},
|
||||
});
|
||||
|
||||
expect(result).toEqual(['execute_code', 'file_search', 'web_search']);
|
||||
expect(result).toEqual(['execute_code', 'file_search', 'web_search', 'memory']);
|
||||
expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ const systemTools = {
|
|||
[Tools.execute_code]: true,
|
||||
[Tools.file_search]: true,
|
||||
[Tools.web_search]: true,
|
||||
[Tools.memory]: true,
|
||||
};
|
||||
|
||||
const MAX_SEARCH_LEN = 100;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
createDeleteMemoryTool,
|
||||
getRequestMemories,
|
||||
invalidateRequestMemories,
|
||||
agentHasInlineMemoryTools,
|
||||
} from './memory';
|
||||
|
||||
jest.mock('~/stream/GenerationJobManager');
|
||||
|
|
@ -663,6 +664,30 @@ describe('createMemoryTool tokenLimit enforcement', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('agentHasInlineMemoryTools', () => {
|
||||
it('returns false for a nullish agent', () => {
|
||||
expect(agentHasInlineMemoryTools(null)).toBe(false);
|
||||
expect(agentHasInlineMemoryTools(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it('honors an explicit memoryToolsRegistered flag over the raw marker', () => {
|
||||
/** Initialized config whose registration was denied (memoryAvailable false)
|
||||
* but whose raw `memory` marker survived in tools must not be treated as
|
||||
* memory-enabled. */
|
||||
expect(agentHasInlineMemoryTools({ memoryToolsRegistered: false, tools: ['memory'] })).toBe(
|
||||
false,
|
||||
);
|
||||
expect(agentHasInlineMemoryTools({ memoryToolsRegistered: true, tools: [] })).toBe(true);
|
||||
});
|
||||
|
||||
it('falls back to the raw memory marker when no flag is present', () => {
|
||||
expect(agentHasInlineMemoryTools({ tools: ['memory'] })).toBe(true);
|
||||
expect(agentHasInlineMemoryTools({ tools: [{ name: 'memory' }] })).toBe(true);
|
||||
expect(agentHasInlineMemoryTools({ tools: ['execute_code'] })).toBe(false);
|
||||
expect(agentHasInlineMemoryTools({ tools: [] })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRequestMemories caching', () => {
|
||||
it('memoizes per request, then re-fetches after invalidation', async () => {
|
||||
const getFormattedMemories = jest
|
||||
|
|
|
|||
|
|
@ -447,8 +447,12 @@ export function agentHasInlineMemoryTools(agent: InlineMemoryAgent): boolean {
|
|||
if (!agent) {
|
||||
return false;
|
||||
}
|
||||
if (agent.memoryToolsRegistered === true) {
|
||||
return true;
|
||||
/** An initialized config carries an explicit boolean: honor it so an agent
|
||||
* whose registration was denied (`false`) is not treated as memory-enabled
|
||||
* just because the raw `memory` marker survives in `tools`. Fall back to the
|
||||
* marker only for the raw agent, where the flag is absent. */
|
||||
if (typeof agent.memoryToolsRegistered === 'boolean') {
|
||||
return agent.memoryToolsRegistered;
|
||||
}
|
||||
return (agent.tools ?? []).some(
|
||||
(entry) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue