🦙 fix: Memory Agent Fails to Initialize with Ollama Provider (#11680)

Fixed an issue where memory agents would fail with 'Provider Ollama not supported'
error when using Ollama as a custom endpoint. The getCustomEndpointConfig function
was only normalizing the endpoint config name but not the endpoint parameter
during comparison.

Changes:
- Modified getCustomEndpointConfig to normalize both sides of the endpoint comparison
- Added comprehensive test coverage for getCustomEndpointConfig including:
  - Test for case-insensitive Ollama endpoint matching (main fix)
  - Tests for various edge cases and error handling

This ensures that endpoint name matching works correctly for Ollama regardless
of case sensitivity in the configuration.
This commit is contained in:
Callum Keogan 2026-02-13 15:43:25 +00:00 committed by GitHub
parent 2e42378b16
commit 8e3b717e99
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 76 additions and 4 deletions

View file

@ -1,7 +1,7 @@
import { getTransactionsConfig, getBalanceConfig } from './config';
import { getTransactionsConfig, getBalanceConfig, getCustomEndpointConfig } from './config';
import { logger } from '@librechat/data-schemas';
import { FileSources } from 'librechat-data-provider';
import type { TCustomConfig } from 'librechat-data-provider';
import { FileSources, EModelEndpoint } from 'librechat-data-provider';
import type { TCustomConfig, TEndpoint } from 'librechat-data-provider';
import type { AppConfig } from '@librechat/data-schemas';
// Helper function to create a minimal AppConfig for testing
@ -282,3 +282,75 @@ describe('getBalanceConfig', () => {
});
});
});
describe('getCustomEndpointConfig', () => {
describe('when appConfig is not provided', () => {
it('should throw an error', () => {
expect(() => getCustomEndpointConfig({ endpoint: 'test' })).toThrow(
'Config not found for the test custom endpoint.',
);
});
});
describe('when appConfig is provided', () => {
it('should return undefined when no custom endpoints are configured', () => {
const appConfig = createTestAppConfig();
const result = getCustomEndpointConfig({ endpoint: 'test', appConfig });
expect(result).toBeUndefined();
});
it('should return the matching endpoint config when found', () => {
const appConfig = createTestAppConfig({
endpoints: {
[EModelEndpoint.custom]: [
{
name: 'TestEndpoint',
apiKey: 'test-key',
} as TEndpoint,
],
},
});
const result = getCustomEndpointConfig({ endpoint: 'TestEndpoint', appConfig });
expect(result).toEqual({
name: 'TestEndpoint',
apiKey: 'test-key',
});
});
it('should handle case-insensitive matching for Ollama endpoint', () => {
const appConfig = createTestAppConfig({
endpoints: {
[EModelEndpoint.custom]: [
{
name: 'Ollama',
apiKey: 'ollama-key',
} as TEndpoint,
],
},
});
const result = getCustomEndpointConfig({ endpoint: 'Ollama', appConfig });
expect(result).toEqual({
name: 'Ollama',
apiKey: 'ollama-key',
});
});
it('should handle mixed case endpoint names', () => {
const appConfig = createTestAppConfig({
endpoints: {
[EModelEndpoint.custom]: [
{
name: 'CustomAI',
apiKey: 'custom-key',
} as TEndpoint,
],
},
});
const result = getCustomEndpointConfig({ endpoint: 'customai', appConfig });
expect(result).toBeUndefined();
});
});
});

View file

@ -64,7 +64,7 @@ export const getCustomEndpointConfig = ({
const customEndpoints = appConfig.endpoints?.[EModelEndpoint.custom] ?? [];
return customEndpoints.find(
(endpointConfig) => normalizeEndpointName(endpointConfig.name) === endpoint,
(endpointConfig) => normalizeEndpointName(endpointConfig.name) === normalizeEndpointName(endpoint),
);
};