mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-22 11:20:15 +01:00
refactor: streamline endpoint configuration and enhance appConfig usage across services
This commit is contained in:
parent
647b1bbac6
commit
71a14517cd
10 changed files with 103 additions and 107 deletions
|
|
@ -7,6 +7,7 @@ const {
|
||||||
createRun,
|
createRun,
|
||||||
Tokenizer,
|
Tokenizer,
|
||||||
checkAccess,
|
checkAccess,
|
||||||
|
hasCustomUserVars,
|
||||||
memoryInstructions,
|
memoryInstructions,
|
||||||
formatContentStrings,
|
formatContentStrings,
|
||||||
createMemoryProcessor,
|
createMemoryProcessor,
|
||||||
|
|
@ -39,12 +40,7 @@ const {
|
||||||
deleteMemory,
|
deleteMemory,
|
||||||
setMemory,
|
setMemory,
|
||||||
} = require('~/models');
|
} = require('~/models');
|
||||||
const {
|
const { checkCapability, getMCPAuthMap, getAppConfig } = require('~/server/services/Config');
|
||||||
hasCustomUserVars,
|
|
||||||
checkCapability,
|
|
||||||
getMCPAuthMap,
|
|
||||||
getAppConfig,
|
|
||||||
} = require('~/server/services/Config');
|
|
||||||
const { addCacheControl, createContextHandlers } = require('~/app/clients/prompts');
|
const { addCacheControl, createContextHandlers } = require('~/app/clients/prompts');
|
||||||
const { initializeAgent } = require('~/server/services/Endpoints/agents/agent');
|
const { initializeAgent } = require('~/server/services/Endpoints/agents/agent');
|
||||||
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
|
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
|
||||||
|
|
@ -917,7 +913,7 @@ class AgentClient extends BaseClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (await hasCustomUserVars()) {
|
if (hasCustomUserVars(appConfig)) {
|
||||||
config.configurable.userMCPAuthMap = await getMCPAuthMap({
|
config.configurable.userMCPAuthMap = await getMCPAuthMap({
|
||||||
tools: agent.tools,
|
tools: agent.tools,
|
||||||
userId: this.options.req.user.id,
|
userId: this.options.req.user.id,
|
||||||
|
|
@ -1102,7 +1098,7 @@ class AgentClient extends BaseClient {
|
||||||
model: agent.model || agent.model_parameters.model,
|
model: agent.model || agent.model_parameters.model,
|
||||||
};
|
};
|
||||||
|
|
||||||
let titleProviderConfig = await getProviderConfig(endpoint);
|
let titleProviderConfig = getProviderConfig({ provider: endpoint, appConfig });
|
||||||
|
|
||||||
/** @type {TEndpoint | undefined} */
|
/** @type {TEndpoint | undefined} */
|
||||||
const endpointConfig =
|
const endpointConfig =
|
||||||
|
|
@ -1117,7 +1113,10 @@ class AgentClient extends BaseClient {
|
||||||
|
|
||||||
if (endpointConfig?.titleEndpoint && endpointConfig.titleEndpoint !== endpoint) {
|
if (endpointConfig?.titleEndpoint && endpointConfig.titleEndpoint !== endpoint) {
|
||||||
try {
|
try {
|
||||||
titleProviderConfig = await getProviderConfig(endpointConfig.titleEndpoint);
|
titleProviderConfig = getProviderConfig({
|
||||||
|
provider: endpointConfig.titleEndpoint,
|
||||||
|
appConfig,
|
||||||
|
});
|
||||||
endpoint = endpointConfig.titleEndpoint;
|
endpoint = endpointConfig.titleEndpoint;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
|
|
@ -1126,7 +1125,7 @@ class AgentClient extends BaseClient {
|
||||||
);
|
);
|
||||||
// Fall back to original provider config
|
// Fall back to original provider config
|
||||||
endpoint = agent.endpoint;
|
endpoint = agent.endpoint;
|
||||||
titleProviderConfig = await getProviderConfig(endpoint);
|
titleProviderConfig = getProviderConfig({ provider: endpoint, appConfig });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,5 @@
|
||||||
const { logger } = require('@librechat/data-schemas');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
const { EModelEndpoint } = require('librechat-data-provider');
|
const { getUserMCPAuthMap } = require('@librechat/api');
|
||||||
const { isEnabled, getUserMCPAuthMap, normalizeEndpointName } = require('@librechat/api');
|
|
||||||
const { getAppConfig } = require('./app');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the configuration object
|
|
||||||
* @function getBalanceConfig
|
|
||||||
* @param {Object} params
|
|
||||||
* @param {string} [params.role]
|
|
||||||
* @returns {Promise<TCustomConfig['balance'] | null>}
|
|
||||||
* */
|
|
||||||
async function getBalanceConfig({ role }) {
|
|
||||||
const isLegacyEnabled = isEnabled(process.env.CHECK_BALANCE);
|
|
||||||
const startBalance = process.env.START_BALANCE;
|
|
||||||
/** @type {TCustomConfig['balance']} */
|
|
||||||
const config = {
|
|
||||||
enabled: isLegacyEnabled,
|
|
||||||
startBalance: startBalance != null && startBalance ? parseInt(startBalance, 10) : undefined,
|
|
||||||
};
|
|
||||||
const appConfig = await getAppConfig({ role });
|
|
||||||
if (!appConfig) {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
return { ...config, ...(appConfig?.['balance'] ?? {}) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string | EModelEndpoint} endpoint
|
|
||||||
* @returns {Promise<TEndpoint | undefined>}
|
|
||||||
*/
|
|
||||||
const getCustomEndpointConfig = async (endpoint) => {
|
|
||||||
const appConfig = await getAppConfig();
|
|
||||||
if (!appConfig) {
|
|
||||||
throw new Error(`Config not found for the ${endpoint} custom endpoint.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const customEndpoints = appConfig.endpoints?.[EModelEndpoint.custom] ?? [];
|
|
||||||
return customEndpoints.find(
|
|
||||||
(endpointConfig) => normalizeEndpointName(endpointConfig.name) === endpoint,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
|
|
@ -67,18 +26,6 @@ async function getMCPAuthMap({ userId, tools, findPluginAuthsByKeys }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<boolean>}
|
|
||||||
*/
|
|
||||||
async function hasCustomUserVars() {
|
|
||||||
const customConfig = await getAppConfig();
|
|
||||||
const mcpServers = customConfig?.mcpConfig;
|
|
||||||
return Object.values(mcpServers ?? {}).some((server) => server.customUserVars);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getMCPAuthMap,
|
getMCPAuthMap,
|
||||||
getBalanceConfig,
|
|
||||||
hasCustomUserVars,
|
|
||||||
getCustomEndpointConfig,
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ const initializeAgent = async ({
|
||||||
})) ?? {};
|
})) ?? {};
|
||||||
|
|
||||||
agent.endpoint = provider;
|
agent.endpoint = provider;
|
||||||
const { getOptions, overrideProvider } = await getProviderConfig(provider);
|
const { getOptions, overrideProvider } = getProviderConfig({ provider, appConfig });
|
||||||
if (overrideProvider !== agent.provider) {
|
if (overrideProvider !== agent.provider) {
|
||||||
agent.provider = overrideProvider;
|
agent.provider = overrideProvider;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const { logger } = require('@librechat/data-schemas');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
const { validateAgentModel } = require('@librechat/api');
|
|
||||||
const { createContentAggregator } = require('@librechat/agents');
|
const { createContentAggregator } = require('@librechat/agents');
|
||||||
|
const { validateAgentModel, getCustomEndpointConfig } = require('@librechat/api');
|
||||||
const {
|
const {
|
||||||
Constants,
|
Constants,
|
||||||
EModelEndpoint,
|
EModelEndpoint,
|
||||||
|
|
@ -11,11 +11,11 @@ const {
|
||||||
createToolEndCallback,
|
createToolEndCallback,
|
||||||
getDefaultHandlers,
|
getDefaultHandlers,
|
||||||
} = require('~/server/controllers/agents/callbacks');
|
} = require('~/server/controllers/agents/callbacks');
|
||||||
const { getCustomEndpointConfig, getAppConfig } = require('~/server/services/Config');
|
|
||||||
const { initializeAgent } = require('~/server/services/Endpoints/agents/agent');
|
const { initializeAgent } = require('~/server/services/Endpoints/agents/agent');
|
||||||
const { getModelsConfig } = require('~/server/controllers/ModelController');
|
const { getModelsConfig } = require('~/server/controllers/ModelController');
|
||||||
const { loadAgentTools } = require('~/server/services/ToolService');
|
const { loadAgentTools } = require('~/server/services/ToolService');
|
||||||
const AgentClient = require('~/server/controllers/agents/client');
|
const AgentClient = require('~/server/controllers/agents/client');
|
||||||
|
const { getAppConfig } = require('~/server/services/Config');
|
||||||
const { getAgent } = require('~/models/Agent');
|
const { getAgent } = require('~/models/Agent');
|
||||||
const { logViolation } = require('~/cache');
|
const { logViolation } = require('~/cache');
|
||||||
|
|
||||||
|
|
@ -147,7 +147,10 @@ const initializeClient = async ({ req, res, endpointOption }) => {
|
||||||
let endpointConfig = appConfig.endpoints?.[primaryConfig.endpoint];
|
let endpointConfig = appConfig.endpoints?.[primaryConfig.endpoint];
|
||||||
if (!isAgentsEndpoint(primaryConfig.endpoint) && !endpointConfig) {
|
if (!isAgentsEndpoint(primaryConfig.endpoint) && !endpointConfig) {
|
||||||
try {
|
try {
|
||||||
endpointConfig = await getCustomEndpointConfig(primaryConfig.endpoint);
|
endpointConfig = getCustomEndpointConfig({
|
||||||
|
endpoint: primaryConfig.endpoint,
|
||||||
|
appConfig,
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
'[api/server/controllers/agents/client.js #titleConvo] Error getting custom endpoint config',
|
'[api/server/controllers/agents/client.js #titleConvo] Error getting custom endpoint config',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
const { Providers } = require('@librechat/agents');
|
||||||
|
const { isUserProvided, getCustomEndpointConfig } = require('@librechat/api');
|
||||||
|
const { getOpenAIConfig, createHandleLLMNewToken, resolveHeaders } = require('@librechat/api');
|
||||||
const {
|
const {
|
||||||
CacheKeys,
|
CacheKeys,
|
||||||
ErrorTypes,
|
ErrorTypes,
|
||||||
|
|
@ -5,13 +8,10 @@ const {
|
||||||
FetchTokenConfig,
|
FetchTokenConfig,
|
||||||
extractEnvVariable,
|
extractEnvVariable,
|
||||||
} = require('librechat-data-provider');
|
} = require('librechat-data-provider');
|
||||||
const { Providers } = require('@librechat/agents');
|
|
||||||
const { getOpenAIConfig, createHandleLLMNewToken, resolveHeaders } = require('@librechat/api');
|
|
||||||
const { getUserKeyValues, checkUserKeyExpiry } = require('~/server/services/UserService');
|
const { getUserKeyValues, checkUserKeyExpiry } = require('~/server/services/UserService');
|
||||||
const { getCustomEndpointConfig, getAppConfig } = require('~/server/services/Config');
|
|
||||||
const { fetchModels } = require('~/server/services/ModelService');
|
const { fetchModels } = require('~/server/services/ModelService');
|
||||||
|
const { getAppConfig } = require('~/server/services/Config');
|
||||||
const OpenAIClient = require('~/app/clients/OpenAIClient');
|
const OpenAIClient = require('~/app/clients/OpenAIClient');
|
||||||
const { isUserProvided } = require('~/server/utils');
|
|
||||||
const getLogStores = require('~/cache/getLogStores');
|
const getLogStores = require('~/cache/getLogStores');
|
||||||
|
|
||||||
const { PROXY } = process.env;
|
const { PROXY } = process.env;
|
||||||
|
|
@ -21,7 +21,10 @@ const initializeClient = async ({ req, res, endpointOption, optionsOnly, overrid
|
||||||
const { key: expiresAt } = req.body;
|
const { key: expiresAt } = req.body;
|
||||||
const endpoint = overrideEndpoint ?? req.body.endpoint;
|
const endpoint = overrideEndpoint ?? req.body.endpoint;
|
||||||
|
|
||||||
const endpointConfig = await getCustomEndpointConfig(endpoint);
|
const endpointConfig = getCustomEndpointConfig({
|
||||||
|
endpoint,
|
||||||
|
appConfig,
|
||||||
|
});
|
||||||
if (!endpointConfig) {
|
if (!endpointConfig) {
|
||||||
throw new Error(`Config not found for the ${endpoint} custom endpoint.`);
|
throw new Error(`Config not found for the ${endpoint} custom endpoint.`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,16 @@
|
||||||
const initializeClient = require('./initialize');
|
const initializeClient = require('./initialize');
|
||||||
|
|
||||||
jest.mock('@librechat/api', () => ({
|
jest.mock('@librechat/api', () => ({
|
||||||
|
...jest.requireActual('@librechat/api'),
|
||||||
resolveHeaders: jest.fn(),
|
resolveHeaders: jest.fn(),
|
||||||
getOpenAIConfig: jest.fn(),
|
getOpenAIConfig: jest.fn(),
|
||||||
createHandleLLMNewToken: jest.fn(),
|
createHandleLLMNewToken: jest.fn(),
|
||||||
}));
|
getCustomEndpointConfig: jest.fn().mockReturnValue({
|
||||||
|
apiKey: 'test-key',
|
||||||
jest.mock('librechat-data-provider', () => ({
|
baseURL: 'https://test.com',
|
||||||
CacheKeys: { TOKEN_CONFIG: 'token_config' },
|
headers: { 'x-user': '{{LIBRECHAT_USER_ID}}', 'x-email': '{{LIBRECHAT_USER_EMAIL}}' },
|
||||||
ErrorTypes: { NO_USER_KEY: 'NO_USER_KEY', NO_BASE_URL: 'NO_BASE_URL' },
|
models: { default: ['test-model'] },
|
||||||
envVarRegex: /\$\{([^}]+)\}/,
|
}),
|
||||||
FetchTokenConfig: {},
|
|
||||||
extractEnvVariable: jest.fn((value) => value),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('@librechat/agents', () => ({
|
|
||||||
Providers: { OLLAMA: 'ollama' },
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('~/server/services/UserService', () => ({
|
jest.mock('~/server/services/UserService', () => ({
|
||||||
|
|
@ -24,12 +19,6 @@ jest.mock('~/server/services/UserService', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('~/server/services/Config', () => ({
|
jest.mock('~/server/services/Config', () => ({
|
||||||
getCustomEndpointConfig: jest.fn().mockResolvedValue({
|
|
||||||
apiKey: 'test-key',
|
|
||||||
baseURL: 'https://test.com',
|
|
||||||
headers: { 'x-user': '{{LIBRECHAT_USER_ID}}', 'x-email': '{{LIBRECHAT_USER_EMAIL}}' },
|
|
||||||
models: { default: ['test-model'] },
|
|
||||||
}),
|
|
||||||
getAppConfig: jest.fn().mockResolvedValue({
|
getAppConfig: jest.fn().mockResolvedValue({
|
||||||
'test-endpoint': {
|
'test-endpoint': {
|
||||||
apiKey: 'test-key',
|
apiKey: 'test-key',
|
||||||
|
|
@ -48,10 +37,6 @@ jest.mock('~/app/clients/OpenAIClient', () => {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('~/server/utils', () => ({
|
|
||||||
isUserProvided: jest.fn().mockReturnValue(false),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('~/cache/getLogStores', () =>
|
jest.mock('~/cache/getLogStores', () =>
|
||||||
jest.fn().mockReturnValue({
|
jest.fn().mockReturnValue({
|
||||||
get: jest.fn(),
|
get: jest.fn(),
|
||||||
|
|
@ -61,13 +46,25 @@ jest.mock('~/cache/getLogStores', () =>
|
||||||
describe('custom/initializeClient', () => {
|
describe('custom/initializeClient', () => {
|
||||||
const mockRequest = {
|
const mockRequest = {
|
||||||
body: { endpoint: 'test-endpoint' },
|
body: { endpoint: 'test-endpoint' },
|
||||||
user: { id: 'user-123', email: 'test@example.com' },
|
user: { id: 'user-123', email: 'test@example.com', role: 'user' },
|
||||||
app: { locals: {} },
|
app: { locals: {} },
|
||||||
};
|
};
|
||||||
const mockResponse = {};
|
const mockResponse = {};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
const { getCustomEndpointConfig, resolveHeaders, getOpenAIConfig } = require('@librechat/api');
|
||||||
|
getCustomEndpointConfig.mockReturnValue({
|
||||||
|
apiKey: 'test-key',
|
||||||
|
baseURL: 'https://test.com',
|
||||||
|
headers: { 'x-user': '{{LIBRECHAT_USER_ID}}', 'x-email': '{{LIBRECHAT_USER_EMAIL}}' },
|
||||||
|
models: { default: ['test-model'] },
|
||||||
|
});
|
||||||
|
resolveHeaders.mockReturnValue({ 'x-user': 'user-123', 'x-email': 'test@example.com' });
|
||||||
|
getOpenAIConfig.mockReturnValue({
|
||||||
|
useLegacyContent: true,
|
||||||
|
endpointTokenConfig: null,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls resolveHeaders with headers, user, and body for body placeholder support', async () => {
|
it('calls resolveHeaders with headers, user, and body for body placeholder support', async () => {
|
||||||
|
|
@ -75,14 +72,14 @@ describe('custom/initializeClient', () => {
|
||||||
await initializeClient({ req: mockRequest, res: mockResponse, optionsOnly: true });
|
await initializeClient({ req: mockRequest, res: mockResponse, optionsOnly: true });
|
||||||
expect(resolveHeaders).toHaveBeenCalledWith({
|
expect(resolveHeaders).toHaveBeenCalledWith({
|
||||||
headers: { 'x-user': '{{LIBRECHAT_USER_ID}}', 'x-email': '{{LIBRECHAT_USER_EMAIL}}' },
|
headers: { 'x-user': '{{LIBRECHAT_USER_ID}}', 'x-email': '{{LIBRECHAT_USER_EMAIL}}' },
|
||||||
user: { id: 'user-123', email: 'test@example.com' },
|
user: { id: 'user-123', email: 'test@example.com', role: 'user' },
|
||||||
body: { endpoint: 'test-endpoint' }, // body - supports {{LIBRECHAT_BODY_*}} placeholders
|
body: { endpoint: 'test-endpoint' }, // body - supports {{LIBRECHAT_BODY_*}} placeholders
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws if endpoint config is missing', async () => {
|
it('throws if endpoint config is missing', async () => {
|
||||||
const { getCustomEndpointConfig } = require('~/server/services/Config');
|
const { getCustomEndpointConfig } = require('@librechat/api');
|
||||||
getCustomEndpointConfig.mockResolvedValueOnce(null);
|
getCustomEndpointConfig.mockReturnValueOnce(null);
|
||||||
await expect(
|
await expect(
|
||||||
initializeClient({ req: mockRequest, res: mockResponse, optionsOnly: true }),
|
initializeClient({ req: mockRequest, res: mockResponse, optionsOnly: true }),
|
||||||
).rejects.toThrow('Config not found for the test-endpoint custom endpoint.');
|
).rejects.toThrow('Config not found for the test-endpoint custom endpoint.');
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
const { Providers } = require('@librechat/agents');
|
const { Providers } = require('@librechat/agents');
|
||||||
const { EModelEndpoint } = require('librechat-data-provider');
|
const { EModelEndpoint } = require('librechat-data-provider');
|
||||||
|
const { getCustomEndpointConfig } = require('@librechat/api');
|
||||||
const initAnthropic = require('~/server/services/Endpoints/anthropic/initialize');
|
const initAnthropic = require('~/server/services/Endpoints/anthropic/initialize');
|
||||||
const getBedrockOptions = require('~/server/services/Endpoints/bedrock/options');
|
const getBedrockOptions = require('~/server/services/Endpoints/bedrock/options');
|
||||||
const initOpenAI = require('~/server/services/Endpoints/openAI/initialize');
|
const initOpenAI = require('~/server/services/Endpoints/openAI/initialize');
|
||||||
const initCustom = require('~/server/services/Endpoints/custom/initialize');
|
const initCustom = require('~/server/services/Endpoints/custom/initialize');
|
||||||
const initGoogle = require('~/server/services/Endpoints/google/initialize');
|
const initGoogle = require('~/server/services/Endpoints/google/initialize');
|
||||||
const { getCustomEndpointConfig } = require('~/server/services/Config');
|
|
||||||
|
|
||||||
/** Check if the provider is a known custom provider
|
/** Check if the provider is a known custom provider
|
||||||
* @param {string | undefined} [provider] - The provider string
|
* @param {string | undefined} [provider] - The provider string
|
||||||
|
|
@ -31,14 +31,16 @@ const providerConfigMap = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the provider configuration and override endpoint based on the provider string
|
* Get the provider configuration and override endpoint based on the provider string
|
||||||
* @param {string} provider - The provider string
|
* @param {Object} params
|
||||||
* @returns {Promise<{
|
* @param {string} params.provider - The provider string
|
||||||
* getOptions: Function,
|
* @param {AppConfig} params.appConfig - The application configuration
|
||||||
|
* @returns {{
|
||||||
|
* getOptions: (typeof providerConfigMap)[keyof typeof providerConfigMap],
|
||||||
* overrideProvider: string,
|
* overrideProvider: string,
|
||||||
* customEndpointConfig?: TEndpoint
|
* customEndpointConfig?: TEndpoint
|
||||||
* }>}
|
* }}
|
||||||
*/
|
*/
|
||||||
async function getProviderConfig(provider) {
|
function getProviderConfig({ provider, appConfig }) {
|
||||||
let getOptions = providerConfigMap[provider];
|
let getOptions = providerConfigMap[provider];
|
||||||
let overrideProvider = provider;
|
let overrideProvider = provider;
|
||||||
/** @type {TEndpoint | undefined} */
|
/** @type {TEndpoint | undefined} */
|
||||||
|
|
@ -48,7 +50,7 @@ async function getProviderConfig(provider) {
|
||||||
overrideProvider = provider.toLowerCase();
|
overrideProvider = provider.toLowerCase();
|
||||||
getOptions = providerConfigMap[overrideProvider];
|
getOptions = providerConfigMap[overrideProvider];
|
||||||
} else if (!getOptions) {
|
} else if (!getOptions) {
|
||||||
customEndpointConfig = await getCustomEndpointConfig(provider);
|
customEndpointConfig = getCustomEndpointConfig({ endpoint: provider, appConfig });
|
||||||
if (!customEndpointConfig) {
|
if (!customEndpointConfig) {
|
||||||
throw new Error(`Provider ${provider} not supported`);
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +59,7 @@ async function getProviderConfig(provider) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isKnownCustomProvider(overrideProvider) && !customEndpointConfig) {
|
if (isKnownCustomProvider(overrideProvider) && !customEndpointConfig) {
|
||||||
customEndpointConfig = await getCustomEndpointConfig(provider);
|
customEndpointConfig = getCustomEndpointConfig({ endpoint: provider, appConfig });
|
||||||
if (!customEndpointConfig) {
|
if (!customEndpointConfig) {
|
||||||
throw new Error(`Provider ${provider} not supported`);
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
packages/api/src/app/config.ts
Normal file
43
packages/api/src/app/config.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { EModelEndpoint, removeNullishValues } from 'librechat-data-provider';
|
||||||
|
import type { TCustomConfig, TEndpoint } from 'librechat-data-provider';
|
||||||
|
import type { AppConfig } from '~/types';
|
||||||
|
import { isEnabled, normalizeEndpointName } from '~/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the balance configuration object
|
||||||
|
* */
|
||||||
|
export function getBalanceConfig(appConfig?: AppConfig): Partial<TCustomConfig['balance']> | null {
|
||||||
|
const isLegacyEnabled = isEnabled(process.env.CHECK_BALANCE);
|
||||||
|
const startBalance = process.env.START_BALANCE;
|
||||||
|
/** @type {} */
|
||||||
|
const config: Partial<TCustomConfig['balance']> = removeNullishValues({
|
||||||
|
enabled: isLegacyEnabled,
|
||||||
|
startBalance: startBalance != null && startBalance ? parseInt(startBalance, 10) : undefined,
|
||||||
|
});
|
||||||
|
if (!appConfig) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
return { ...config, ...(appConfig?.['balance'] ?? {}) };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCustomEndpointConfig = ({
|
||||||
|
endpoint,
|
||||||
|
appConfig,
|
||||||
|
}: {
|
||||||
|
endpoint: string | EModelEndpoint;
|
||||||
|
appConfig?: AppConfig;
|
||||||
|
}): Partial<TEndpoint> | undefined => {
|
||||||
|
if (!appConfig) {
|
||||||
|
throw new Error(`Config not found for the ${endpoint} custom endpoint.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const customEndpoints = appConfig.endpoints?.[EModelEndpoint.custom] ?? [];
|
||||||
|
return customEndpoints.find(
|
||||||
|
(endpointConfig) => normalizeEndpointName(endpointConfig.name) === endpoint,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function hasCustomUserVars(appConfig?: AppConfig): boolean {
|
||||||
|
const mcpServers = appConfig?.mcpConfig;
|
||||||
|
return Object.values(mcpServers ?? {}).some((server) => server.customUserVars);
|
||||||
|
}
|
||||||
1
packages/api/src/app/index.ts
Normal file
1
packages/api/src/app/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './config';
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from './app';
|
||||||
/* MCP */
|
/* MCP */
|
||||||
export * from './mcp/MCPManager';
|
export * from './mcp/MCPManager';
|
||||||
export * from './mcp/oauth';
|
export * from './mcp/oauth';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue