mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
🚀 feat: gpt-4o-mini (#3384)
* feat: `gpt-4o-mini` * feat: retrival * fix: Update order of model token values for 'gpt-4o' and 'gpt-4o-mini' * fix: Update order of model token values for 'gpt-4o' and 'gpt-4o-mini' * fix: Update order of model token values for 'gpt-4o' and 'gpt-4o-mini' * fix: add jsdoc * fix: Update order of model token values for 'gpt-4o' and 'gpt-4o-mini' --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
f6125ccd59
commit
ee4dd1b2e9
8 changed files with 99 additions and 65 deletions
|
|
@ -144,7 +144,7 @@ GOOGLE_KEY=user_provided
|
||||||
#============#
|
#============#
|
||||||
|
|
||||||
OPENAI_API_KEY=user_provided
|
OPENAI_API_KEY=user_provided
|
||||||
# OPENAI_MODELS=gpt-4o,gpt-3.5-turbo-0125,gpt-3.5-turbo-0301,gpt-3.5-turbo,gpt-4,gpt-4-0613,gpt-4-vision-preview,gpt-3.5-turbo-0613,gpt-3.5-turbo-16k-0613,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview,gpt-3.5-turbo-1106,gpt-3.5-turbo-instruct,gpt-3.5-turbo-instruct-0914,gpt-3.5-turbo-16k
|
# OPENAI_MODELS=gpt-4o,gpt-4o-mini,gpt-3.5-turbo-0125,gpt-3.5-turbo-0301,gpt-3.5-turbo,gpt-4,gpt-4-0613,gpt-4-vision-preview,gpt-3.5-turbo-0613,gpt-3.5-turbo-16k-0613,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview,gpt-3.5-turbo-1106,gpt-3.5-turbo-instruct,gpt-3.5-turbo-instruct-0914,gpt-3.5-turbo-16k
|
||||||
|
|
||||||
DEBUG_OPENAI=false
|
DEBUG_OPENAI=false
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ DEBUG_OPENAI=false
|
||||||
|
|
||||||
ASSISTANTS_API_KEY=user_provided
|
ASSISTANTS_API_KEY=user_provided
|
||||||
# ASSISTANTS_BASE_URL=
|
# ASSISTANTS_BASE_URL=
|
||||||
# ASSISTANTS_MODELS=gpt-4o,gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview
|
# ASSISTANTS_MODELS=gpt-4o,gpt-4o-mini,gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview
|
||||||
|
|
||||||
#==========================#
|
#==========================#
|
||||||
# Azure Assistants API #
|
# Azure Assistants API #
|
||||||
|
|
@ -188,7 +188,7 @@ ASSISTANTS_API_KEY=user_provided
|
||||||
# Plugins #
|
# Plugins #
|
||||||
#============#
|
#============#
|
||||||
|
|
||||||
# PLUGIN_MODELS=gpt-4o,gpt-4,gpt-4-turbo-preview,gpt-4-0125-preview,gpt-4-1106-preview,gpt-4-0613,gpt-3.5-turbo,gpt-3.5-turbo-0125,gpt-3.5-turbo-1106,gpt-3.5-turbo-0613
|
# PLUGIN_MODELS=gpt-4o,gpt-4o-mini,gpt-4,gpt-4-turbo-preview,gpt-4-0125-preview,gpt-4-1106-preview,gpt-4-0613,gpt-3.5-turbo,gpt-3.5-turbo-0125,gpt-3.5-turbo-1106,gpt-3.5-turbo-0613
|
||||||
|
|
||||||
DEBUG_PLUGINS=true
|
DEBUG_PLUGINS=true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
- 🔄 Edit, Resubmit, and Continue Messages with Conversation branching
|
- 🔄 Edit, Resubmit, and Continue Messages with Conversation branching
|
||||||
- 🌿 Fork Messages & Conversations for Advanced Context control
|
- 🌿 Fork Messages & Conversations for Advanced Context control
|
||||||
- 💬 Multimodal Chat:
|
- 💬 Multimodal Chat:
|
||||||
- Upload and analyze images with Claude 3, GPT-4 (including `gpt-4o`), and Gemini Vision 📸
|
- Upload and analyze images with Claude 3, GPT-4 (including `gpt-4o` and `gpt-4o-mini`), and Gemini Vision 📸
|
||||||
- Chat with Files using Custom Endpoints, OpenAI, Azure, Anthropic, & Google. 🗃️
|
- Chat with Files using Custom Endpoints, OpenAI, Azure, Anthropic, & Google. 🗃️
|
||||||
- Advanced Agents with Files, Code Interpreter, Tools, and API Actions 🔦
|
- Advanced Agents with Files, Code Interpreter, Tools, and API Actions 🔦
|
||||||
- Available through the [OpenAI Assistants API](https://platform.openai.com/docs/assistants/overview) 🌤️
|
- Available through the [OpenAI Assistants API](https://platform.openai.com/docs/assistants/overview) 🌤️
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ const tokenValues = {
|
||||||
'4k': { prompt: 1.5, completion: 2 },
|
'4k': { prompt: 1.5, completion: 2 },
|
||||||
'16k': { prompt: 3, completion: 4 },
|
'16k': { prompt: 3, completion: 4 },
|
||||||
'gpt-3.5-turbo-1106': { prompt: 1, completion: 2 },
|
'gpt-3.5-turbo-1106': { prompt: 1, completion: 2 },
|
||||||
|
'gpt-4o-mini': { prompt: 0.15, completion: 0.6 },
|
||||||
'gpt-4o': { prompt: 5, completion: 15 },
|
'gpt-4o': { prompt: 5, completion: 15 },
|
||||||
'gpt-4-1106': { prompt: 10, completion: 30 },
|
'gpt-4-1106': { prompt: 10, completion: 30 },
|
||||||
'gpt-3.5-turbo-0125': { prompt: 0.5, completion: 1.5 },
|
'gpt-3.5-turbo-0125': { prompt: 0.5, completion: 1.5 },
|
||||||
|
|
@ -54,6 +55,8 @@ const getValueKey = (model, endpoint) => {
|
||||||
return 'gpt-3.5-turbo-1106';
|
return 'gpt-3.5-turbo-1106';
|
||||||
} else if (modelName.includes('gpt-3.5')) {
|
} else if (modelName.includes('gpt-3.5')) {
|
||||||
return '4k';
|
return '4k';
|
||||||
|
} else if (modelName.includes('gpt-4o-mini')) {
|
||||||
|
return 'gpt-4o-mini';
|
||||||
} else if (modelName.includes('gpt-4o')) {
|
} else if (modelName.includes('gpt-4o')) {
|
||||||
return 'gpt-4o';
|
return 'gpt-4o';
|
||||||
} else if (modelName.includes('gpt-4-vision')) {
|
} else if (modelName.includes('gpt-4-vision')) {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ describe('getValueKey', () => {
|
||||||
expect(getValueKey('gpt-4o-0125')).toBe('gpt-4o');
|
expect(getValueKey('gpt-4o-0125')).toBe('gpt-4o');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return "gpt-4o-mini" for model type of "gpt-4o-mini"', () => {
|
||||||
|
expect(getValueKey('gpt-4o-mini-2024-07-18')).toBe('gpt-4o-mini');
|
||||||
|
expect(getValueKey('openai/gpt-4o-mini')).toBe('gpt-4o-mini');
|
||||||
|
expect(getValueKey('gpt-4o-mini-0718')).toBe('gpt-4o-mini');
|
||||||
|
});
|
||||||
|
|
||||||
it('should return "claude-3-5-sonnet" for model type of "claude-3-5-sonnet-"', () => {
|
it('should return "claude-3-5-sonnet" for model type of "claude-3-5-sonnet-"', () => {
|
||||||
expect(getValueKey('claude-3-5-sonnet-20240620')).toBe('claude-3-5-sonnet');
|
expect(getValueKey('claude-3-5-sonnet-20240620')).toBe('claude-3-5-sonnet');
|
||||||
expect(getValueKey('anthropic/claude-3-5-sonnet')).toBe('claude-3-5-sonnet');
|
expect(getValueKey('anthropic/claude-3-5-sonnet')).toBe('claude-3-5-sonnet');
|
||||||
|
|
@ -109,6 +115,19 @@ describe('getMultiplier', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return the correct multiplier for gpt-4o-mini', () => {
|
||||||
|
const valueKey = getValueKey('gpt-4o-mini-2024-07-18');
|
||||||
|
expect(getMultiplier({ valueKey, tokenType: 'prompt' })).toBe(
|
||||||
|
tokenValues['gpt-4o-mini'].prompt,
|
||||||
|
);
|
||||||
|
expect(getMultiplier({ valueKey, tokenType: 'completion' })).toBe(
|
||||||
|
tokenValues['gpt-4o-mini'].completion,
|
||||||
|
);
|
||||||
|
expect(getMultiplier({ valueKey, tokenType: 'completion' })).not.toBe(
|
||||||
|
tokenValues['gpt-4-1106'].completion,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should derive the valueKey from the model if not provided for new models', () => {
|
it('should derive the valueKey from the model if not provided for new models', () => {
|
||||||
expect(
|
expect(
|
||||||
getMultiplier({ tokenType: 'prompt', model: 'gpt-3.5-turbo-1106-some-other-info' }),
|
getMultiplier({ tokenType: 'prompt', model: 'gpt-3.5-turbo-1106-some-other-info' }),
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,6 @@
|
||||||
const z = require('zod');
|
const z = require('zod');
|
||||||
const { EModelEndpoint } = require('librechat-data-provider');
|
const { EModelEndpoint } = require('librechat-data-provider');
|
||||||
|
|
||||||
const models = [
|
|
||||||
'text-davinci-003',
|
|
||||||
'text-davinci-002',
|
|
||||||
'text-davinci-001',
|
|
||||||
'text-curie-001',
|
|
||||||
'text-babbage-001',
|
|
||||||
'text-ada-001',
|
|
||||||
'davinci',
|
|
||||||
'curie',
|
|
||||||
'babbage',
|
|
||||||
'ada',
|
|
||||||
'code-davinci-002',
|
|
||||||
'code-davinci-001',
|
|
||||||
'code-cushman-002',
|
|
||||||
'code-cushman-001',
|
|
||||||
'davinci-codex',
|
|
||||||
'cushman-codex',
|
|
||||||
'text-davinci-edit-001',
|
|
||||||
'code-davinci-edit-001',
|
|
||||||
'text-embedding-ada-002',
|
|
||||||
'text-similarity-davinci-001',
|
|
||||||
'text-similarity-curie-001',
|
|
||||||
'text-similarity-babbage-001',
|
|
||||||
'text-similarity-ada-001',
|
|
||||||
'text-search-davinci-doc-001',
|
|
||||||
'text-search-curie-doc-001',
|
|
||||||
'text-search-babbage-doc-001',
|
|
||||||
'text-search-ada-doc-001',
|
|
||||||
'code-search-babbage-code-001',
|
|
||||||
'code-search-ada-code-001',
|
|
||||||
'gpt2',
|
|
||||||
'gpt-4',
|
|
||||||
'gpt-4-0314',
|
|
||||||
'gpt-4-32k',
|
|
||||||
'gpt-4-32k-0314',
|
|
||||||
'gpt-3.5-turbo',
|
|
||||||
'gpt-3.5-turbo-0301',
|
|
||||||
];
|
|
||||||
|
|
||||||
const openAIModels = {
|
const openAIModels = {
|
||||||
'gpt-4': 8187, // -5 from max
|
'gpt-4': 8187, // -5 from max
|
||||||
'gpt-4-0613': 8187, // -5 from max
|
'gpt-4-0613': 8187, // -5 from max
|
||||||
|
|
@ -49,6 +10,7 @@ const openAIModels = {
|
||||||
'gpt-4-1106': 127990, // -10 from max
|
'gpt-4-1106': 127990, // -10 from max
|
||||||
'gpt-4-0125': 127990, // -10 from max
|
'gpt-4-0125': 127990, // -10 from max
|
||||||
'gpt-4o': 127990, // -10 from max
|
'gpt-4o': 127990, // -10 from max
|
||||||
|
'gpt-4o-mini': 127990, // -10 from max
|
||||||
'gpt-4-turbo': 127990, // -10 from max
|
'gpt-4-turbo': 127990, // -10 from max
|
||||||
'gpt-4-vision': 127990, // -10 from max
|
'gpt-4-vision': 127990, // -10 from max
|
||||||
'gpt-3.5-turbo': 16375, // -10 from max
|
'gpt-3.5-turbo': 16375, // -10 from max
|
||||||
|
|
@ -101,7 +63,6 @@ const anthropicModels = {
|
||||||
|
|
||||||
const aggregateModels = { ...openAIModels, ...googleModels, ...anthropicModels, ...cohereModels };
|
const aggregateModels = { ...openAIModels, ...googleModels, ...anthropicModels, ...cohereModels };
|
||||||
|
|
||||||
// Order is important here: by model series and context size (gpt-4 then gpt-3, ascending)
|
|
||||||
const maxTokensMap = {
|
const maxTokensMap = {
|
||||||
[EModelEndpoint.azureOpenAI]: openAIModels,
|
[EModelEndpoint.azureOpenAI]: openAIModels,
|
||||||
[EModelEndpoint.openAI]: aggregateModels,
|
[EModelEndpoint.openAI]: aggregateModels,
|
||||||
|
|
@ -110,6 +71,24 @@ const maxTokensMap = {
|
||||||
[EModelEndpoint.anthropic]: anthropicModels,
|
[EModelEndpoint.anthropic]: anthropicModels,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the first matching pattern in the tokens map.
|
||||||
|
* @param {string} modelName
|
||||||
|
* @param {Record<string, number>} tokensMap
|
||||||
|
* @returns {string|null}
|
||||||
|
*/
|
||||||
|
function findMatchingPattern(modelName, tokensMap) {
|
||||||
|
const keys = Object.keys(tokensMap);
|
||||||
|
for (let i = keys.length - 1; i >= 0; i--) {
|
||||||
|
const modelKey = keys[i];
|
||||||
|
if (modelName.includes(modelKey)) {
|
||||||
|
return modelKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the maximum tokens for a given model name. If the exact model name isn't found,
|
* Retrieves the maximum tokens for a given model name. If the exact model name isn't found,
|
||||||
* it searches for partial matches within the model name, checking keys in reverse order.
|
* it searches for partial matches within the model name, checking keys in reverse order.
|
||||||
|
|
@ -143,12 +122,11 @@ function getModelMaxTokens(modelName, endpoint = EModelEndpoint.openAI, endpoint
|
||||||
return tokensMap[modelName];
|
return tokensMap[modelName];
|
||||||
}
|
}
|
||||||
|
|
||||||
const keys = Object.keys(tokensMap);
|
const matchedPattern = findMatchingPattern(modelName, tokensMap);
|
||||||
for (let i = keys.length - 1; i >= 0; i--) {
|
|
||||||
if (modelName.includes(keys[i])) {
|
if (matchedPattern) {
|
||||||
const result = tokensMap[keys[i]];
|
const result = tokensMap[matchedPattern];
|
||||||
return result?.context ?? result;
|
return result?.context ?? result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -181,15 +159,8 @@ function matchModelName(modelName, endpoint = EModelEndpoint.openAI) {
|
||||||
return modelName;
|
return modelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const keys = Object.keys(tokensMap);
|
const matchedPattern = findMatchingPattern(modelName, tokensMap);
|
||||||
for (let i = keys.length - 1; i >= 0; i--) {
|
return matchedPattern || modelName;
|
||||||
const modelKey = keys[i];
|
|
||||||
if (modelName.includes(modelKey)) {
|
|
||||||
return modelKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return modelName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelSchema = z.object({
|
const modelSchema = z.object({
|
||||||
|
|
@ -241,8 +212,47 @@ function processModelData(input) {
|
||||||
return tokenConfig;
|
return tokenConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tiktokenModels = new Set([
|
||||||
|
'text-davinci-003',
|
||||||
|
'text-davinci-002',
|
||||||
|
'text-davinci-001',
|
||||||
|
'text-curie-001',
|
||||||
|
'text-babbage-001',
|
||||||
|
'text-ada-001',
|
||||||
|
'davinci',
|
||||||
|
'curie',
|
||||||
|
'babbage',
|
||||||
|
'ada',
|
||||||
|
'code-davinci-002',
|
||||||
|
'code-davinci-001',
|
||||||
|
'code-cushman-002',
|
||||||
|
'code-cushman-001',
|
||||||
|
'davinci-codex',
|
||||||
|
'cushman-codex',
|
||||||
|
'text-davinci-edit-001',
|
||||||
|
'code-davinci-edit-001',
|
||||||
|
'text-embedding-ada-002',
|
||||||
|
'text-similarity-davinci-001',
|
||||||
|
'text-similarity-curie-001',
|
||||||
|
'text-similarity-babbage-001',
|
||||||
|
'text-similarity-ada-001',
|
||||||
|
'text-search-davinci-doc-001',
|
||||||
|
'text-search-curie-doc-001',
|
||||||
|
'text-search-babbage-doc-001',
|
||||||
|
'text-search-ada-doc-001',
|
||||||
|
'code-search-babbage-code-001',
|
||||||
|
'code-search-ada-code-001',
|
||||||
|
'gpt2',
|
||||||
|
'gpt-4',
|
||||||
|
'gpt-4-0314',
|
||||||
|
'gpt-4-32k',
|
||||||
|
'gpt-4-32k-0314',
|
||||||
|
'gpt-3.5-turbo',
|
||||||
|
'gpt-3.5-turbo-0301',
|
||||||
|
]);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
tiktokenModels: new Set(models),
|
tiktokenModels,
|
||||||
maxTokensMap,
|
maxTokensMap,
|
||||||
inputSchema,
|
inputSchema,
|
||||||
modelSchema,
|
modelSchema,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "librechat-data-provider",
|
"name": "librechat-data-provider",
|
||||||
"version": "0.7.2",
|
"version": "0.7.3",
|
||||||
"description": "data services for librechat apps",
|
"description": "data services for librechat apps",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/index.es.js",
|
"module": "dist/index.es.js",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ export const defaultSocialLogins = ['google', 'facebook', 'openid', 'github', 'd
|
||||||
export const defaultRetrievalModels = [
|
export const defaultRetrievalModels = [
|
||||||
'gpt-4o',
|
'gpt-4o',
|
||||||
'gpt-4o-2024-05-13',
|
'gpt-4o-2024-05-13',
|
||||||
|
'gpt-4o-mini',
|
||||||
|
'gpt-4o-mini-2024-07-18',
|
||||||
'gpt-4-turbo-preview',
|
'gpt-4-turbo-preview',
|
||||||
'gpt-3.5-turbo-0125',
|
'gpt-3.5-turbo-0125',
|
||||||
'gpt-4-0125-preview',
|
'gpt-4-0125-preview',
|
||||||
|
|
@ -530,7 +532,7 @@ const sharedOpenAIModels = [
|
||||||
|
|
||||||
export const defaultModels = {
|
export const defaultModels = {
|
||||||
[EModelEndpoint.azureAssistants]: sharedOpenAIModels,
|
[EModelEndpoint.azureAssistants]: sharedOpenAIModels,
|
||||||
[EModelEndpoint.assistants]: ['gpt-4o', ...sharedOpenAIModels],
|
[EModelEndpoint.assistants]: ['gpt-4o-mini', 'gpt-4o', ...sharedOpenAIModels],
|
||||||
[EModelEndpoint.google]: [
|
[EModelEndpoint.google]: [
|
||||||
'gemini-pro',
|
'gemini-pro',
|
||||||
'gemini-pro-vision',
|
'gemini-pro-vision',
|
||||||
|
|
@ -559,13 +561,12 @@ export const defaultModels = {
|
||||||
'claude-instant-1-100k',
|
'claude-instant-1-100k',
|
||||||
],
|
],
|
||||||
[EModelEndpoint.openAI]: [
|
[EModelEndpoint.openAI]: [
|
||||||
|
'gpt-4o-mini',
|
||||||
'gpt-4o',
|
'gpt-4o',
|
||||||
...sharedOpenAIModels,
|
...sharedOpenAIModels,
|
||||||
'gpt-4-vision-preview',
|
'gpt-4-vision-preview',
|
||||||
'gpt-3.5-turbo-instruct-0914',
|
'gpt-3.5-turbo-instruct-0914',
|
||||||
'gpt-3.5-turbo-0301',
|
|
||||||
'gpt-3.5-turbo-instruct',
|
'gpt-3.5-turbo-instruct',
|
||||||
'text-davinci-003',
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -621,6 +622,7 @@ export const supportsBalanceCheck = {
|
||||||
|
|
||||||
export const visionModels = [
|
export const visionModels = [
|
||||||
'gpt-4o',
|
'gpt-4o',
|
||||||
|
'gpt-4o-mini',
|
||||||
'gpt-4-turbo',
|
'gpt-4-turbo',
|
||||||
'gpt-4-vision',
|
'gpt-4-vision',
|
||||||
'llava',
|
'llava',
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ export enum EAgent {
|
||||||
|
|
||||||
export const agentOptionSettings = {
|
export const agentOptionSettings = {
|
||||||
model: {
|
model: {
|
||||||
default: 'gpt-4o',
|
default: 'gpt-4o-mini',
|
||||||
},
|
},
|
||||||
temperature: {
|
temperature: {
|
||||||
min: 0,
|
min: 0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue