mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-25 11:54:08 +01:00
✨ feat: Implement Token Rates Configuration Loader and Update Config Types
This commit is contained in:
parent
e14df5956a
commit
7dfb386f5a
3 changed files with 78 additions and 1 deletions
|
|
@ -12,6 +12,7 @@ const { agentsConfigSetup } = require('./start/agents');
|
||||||
const { initializeRoles } = require('~/models/Role');
|
const { initializeRoles } = require('~/models/Role');
|
||||||
const { getMCPManager } = require('~/config');
|
const { getMCPManager } = require('~/config');
|
||||||
const paths = require('~/config/paths');
|
const paths = require('~/config/paths');
|
||||||
|
const { loadTokenRatesConfig } = require('./Config/loadTokenRatesConfig');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -21,9 +22,13 @@ const paths = require('~/config/paths');
|
||||||
*/
|
*/
|
||||||
const AppService = async (app) => {
|
const AppService = async (app) => {
|
||||||
await initializeRoles();
|
await initializeRoles();
|
||||||
/** @type {TCustomConfig}*/
|
/** @type {TCustomConfig} */
|
||||||
const config = (await loadCustomConfig()) ?? {};
|
const config = (await loadCustomConfig()) ?? {};
|
||||||
const configDefaults = getConfigDefaults();
|
const configDefaults = getConfigDefaults();
|
||||||
|
const tokenRatesConfig = loadTokenRatesConfig(config, configDefaults);
|
||||||
|
//
|
||||||
|
// // Set the global token rates configuration so that it can be used by the tx.js functions.
|
||||||
|
// setTokenRatesConfig(tokenRatesConfig);
|
||||||
|
|
||||||
const filteredTools = config.filteredTools;
|
const filteredTools = config.filteredTools;
|
||||||
const includedTools = config.includedTools;
|
const includedTools = config.includedTools;
|
||||||
|
|
|
||||||
27
api/server/services/Config/loadTokenRatesConfig.js
Normal file
27
api/server/services/Config/loadTokenRatesConfig.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
const { removeNullishValues } = require('librechat-data-provider');
|
||||||
|
const { logger } = require('~/config');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads custom token rates from the user's YAML config, merging with default token rates if available.
|
||||||
|
*
|
||||||
|
* @param {TCustomConfig | undefined} config - The loaded custom configuration.
|
||||||
|
* @param {TConfigDefaults} [configDefaults] - Optional default configuration values.
|
||||||
|
* @returns {TCustomConfig['tokenRates']} - The final token rates configuration.
|
||||||
|
*/
|
||||||
|
function loadTokenRatesConfig(config, configDefaults) {
|
||||||
|
const userTokenRates = removeNullishValues(config?.tokenRates ?? {});
|
||||||
|
|
||||||
|
if (!configDefaults?.tokenRates) {
|
||||||
|
logger.info(`User tokenRates configuration:\n${JSON.stringify(userTokenRates, null, 2)}`);
|
||||||
|
return userTokenRates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {TCustomConfig['tokenRates']} */
|
||||||
|
const defaultTokenRates = removeNullishValues(configDefaults.tokenRates);
|
||||||
|
const merged = { ...defaultTokenRates, ...userTokenRates };
|
||||||
|
|
||||||
|
logger.info(`Merged tokenRates configuration:\n${JSON.stringify(merged, null, 2)}`);
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { loadTokenRatesConfig };
|
||||||
|
|
@ -505,12 +505,56 @@ export type TStartupConfig = {
|
||||||
helpAndFaqURL: string;
|
helpAndFaqURL: string;
|
||||||
customFooter?: string;
|
customFooter?: string;
|
||||||
modelSpecs?: TSpecsConfig;
|
modelSpecs?: TSpecsConfig;
|
||||||
|
tokenRates?: TTokenRates;
|
||||||
sharedLinksEnabled: boolean;
|
sharedLinksEnabled: boolean;
|
||||||
publicSharedLinksEnabled: boolean;
|
publicSharedLinksEnabled: boolean;
|
||||||
analyticsGtmId?: string;
|
analyticsGtmId?: string;
|
||||||
instanceProjectId: string;
|
instanceProjectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Token cost schema type
|
||||||
|
export type TTokenCost = {
|
||||||
|
prompt?: number;
|
||||||
|
completion?: number;
|
||||||
|
cache?: {
|
||||||
|
write?: number;
|
||||||
|
read?: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Endpoint token rates schema type
|
||||||
|
export type TEndpointTokenRates = Record<string, TTokenCost>;
|
||||||
|
|
||||||
|
// Token rates schema type
|
||||||
|
export type TTokenRates = {
|
||||||
|
openAI?: TEndpointTokenRates;
|
||||||
|
google?: TEndpointTokenRates;
|
||||||
|
anthropic?: TEndpointTokenRates;
|
||||||
|
bedrock?: TEndpointTokenRates;
|
||||||
|
custom?: TEndpointTokenRates;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tokenCostSchema = z.object({
|
||||||
|
prompt: z.number().optional(), // e.g. 1.5 => $1.50 / 1M tokens
|
||||||
|
completion: z.number().optional(), // e.g. 2.0 => $2.00 / 1M tokens
|
||||||
|
cache: z
|
||||||
|
.object({
|
||||||
|
write: z.number().optional(),
|
||||||
|
read: z.number().optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const endpointTokenRatesSchema = z.record(z.string(), tokenCostSchema);
|
||||||
|
|
||||||
|
const tokenRatesSchema = z.object({
|
||||||
|
openAI: endpointTokenRatesSchema.optional(),
|
||||||
|
google: endpointTokenRatesSchema.optional(),
|
||||||
|
anthropic: endpointTokenRatesSchema.optional(),
|
||||||
|
bedrock: endpointTokenRatesSchema.optional(),
|
||||||
|
custom: endpointTokenRatesSchema.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
export const configSchema = z.object({
|
export const configSchema = z.object({
|
||||||
version: z.string(),
|
version: z.string(),
|
||||||
cache: z.boolean().default(true),
|
cache: z.boolean().default(true),
|
||||||
|
|
@ -542,6 +586,7 @@ export const configSchema = z.object({
|
||||||
rateLimits: rateLimitSchema.optional(),
|
rateLimits: rateLimitSchema.optional(),
|
||||||
fileConfig: fileConfigSchema.optional(),
|
fileConfig: fileConfigSchema.optional(),
|
||||||
modelSpecs: specsConfigSchema.optional(),
|
modelSpecs: specsConfigSchema.optional(),
|
||||||
|
tokenRates: tokenRatesSchema.optional(),
|
||||||
endpoints: z
|
endpoints: z
|
||||||
.object({
|
.object({
|
||||||
all: baseEndpointSchema.optional(),
|
all: baseEndpointSchema.optional(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue