mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-25 03:36:12 +01:00
95 lines
3 KiB
TypeScript
95 lines
3 KiB
TypeScript
|
|
import logger from '~/config/winston';
|
||
|
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||
|
|
import type { TCustomConfig } from 'librechat-data-provider';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Normalize the endpoint name to system-expected value.
|
||
|
|
* @param name
|
||
|
|
*/
|
||
|
|
function normalizeEndpointName(name = ''): string {
|
||
|
|
return name.toLowerCase() === 'ollama' ? 'ollama' : name;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets up Model Specs from the config (`librechat.yaml`) file.
|
||
|
|
* @param [endpoints] - The loaded custom configuration for endpoints.
|
||
|
|
* @param [modelSpecs] - The loaded custom configuration for model specs.
|
||
|
|
* @param [interfaceConfig] - The loaded interface configuration.
|
||
|
|
* @returns The processed model specs, if any.
|
||
|
|
*/
|
||
|
|
export function processModelSpecs(
|
||
|
|
endpoints?: TCustomConfig['endpoints'],
|
||
|
|
_modelSpecs?: TCustomConfig['modelSpecs'],
|
||
|
|
interfaceConfig?: TCustomConfig['interface'],
|
||
|
|
): TCustomConfig['modelSpecs'] | undefined {
|
||
|
|
if (!_modelSpecs) {
|
||
|
|
return undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
const list = _modelSpecs.list;
|
||
|
|
const modelSpecs: typeof list = [];
|
||
|
|
|
||
|
|
const customEndpoints = endpoints?.[EModelEndpoint.custom] ?? [];
|
||
|
|
|
||
|
|
if (interfaceConfig?.modelSelect !== true && (_modelSpecs.addedEndpoints?.length ?? 0) > 0) {
|
||
|
|
logger.warn(
|
||
|
|
`To utilize \`addedEndpoints\`, which allows provider/model selections alongside model specs, set \`modelSelect: true\` in the interface configuration.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
\`\`\`yaml
|
||
|
|
interface:
|
||
|
|
modelSelect: true
|
||
|
|
\`\`\`
|
||
|
|
`,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!list || list.length === 0) {
|
||
|
|
return undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (const spec of list) {
|
||
|
|
const currentEndpoint = spec.preset?.endpoint as EModelEndpoint | undefined;
|
||
|
|
if (!currentEndpoint) {
|
||
|
|
logger.warn(
|
||
|
|
'A model spec is missing the `endpoint` field within its `preset`. Skipping model spec...',
|
||
|
|
);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (EModelEndpoint[currentEndpoint] && currentEndpoint !== EModelEndpoint.custom) {
|
||
|
|
modelSpecs.push(spec);
|
||
|
|
continue;
|
||
|
|
} else if (currentEndpoint === EModelEndpoint.custom) {
|
||
|
|
logger.warn(
|
||
|
|
`Model Spec with endpoint "${currentEndpoint}" is not supported. You must specify the name of the custom endpoint (case-sensitive, as defined in your config). Skipping model spec...`,
|
||
|
|
);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
const normalizedName = normalizeEndpointName(currentEndpoint);
|
||
|
|
const endpoint = customEndpoints.find(
|
||
|
|
(customEndpoint) => normalizedName === normalizeEndpointName(customEndpoint.name),
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!endpoint) {
|
||
|
|
logger.warn(`Model spec with endpoint "${currentEndpoint}" was skipped: Endpoint not found in configuration. The \`endpoint\` value must exactly match either a system-defined endpoint or a custom endpoint defined by the user.
|
||
|
|
|
||
|
|
For more information, see the documentation at https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/model_specs#endpoint`);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
modelSpecs.push({
|
||
|
|
...spec,
|
||
|
|
preset: {
|
||
|
|
...spec.preset,
|
||
|
|
endpoint: normalizedName,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
..._modelSpecs,
|
||
|
|
list: modelSpecs,
|
||
|
|
};
|
||
|
|
}
|