mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
🤖 feat: o3-mini (#5581)
* 🤖 feat: `o3-mini`
* chore: re-order vision models list to prioritize gpt-4o as a vision model over o1
This commit is contained in:
parent
fdf0b41d08
commit
33f6093775
6 changed files with 17 additions and 13 deletions
|
|
@ -65,7 +65,7 @@ class OpenAIClient extends BaseClient {
|
||||||
/** @type {OpenAIUsageMetadata | undefined} */
|
/** @type {OpenAIUsageMetadata | undefined} */
|
||||||
this.usage;
|
this.usage;
|
||||||
/** @type {boolean|undefined} */
|
/** @type {boolean|undefined} */
|
||||||
this.isO1Model;
|
this.isOmni;
|
||||||
/** @type {SplitStreamHandler | undefined} */
|
/** @type {SplitStreamHandler | undefined} */
|
||||||
this.streamHandler;
|
this.streamHandler;
|
||||||
}
|
}
|
||||||
|
|
@ -105,8 +105,8 @@ class OpenAIClient extends BaseClient {
|
||||||
this.checkVisionRequest(this.options.attachments);
|
this.checkVisionRequest(this.options.attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
const o1Pattern = /\bo1\b/i;
|
const omniPattern = /\b(o1|o3)\b/i;
|
||||||
this.isO1Model = o1Pattern.test(this.modelOptions.model);
|
this.isOmni = omniPattern.test(this.modelOptions.model);
|
||||||
|
|
||||||
const { OPENROUTER_API_KEY, OPENAI_FORCE_PROMPT } = process.env ?? {};
|
const { OPENROUTER_API_KEY, OPENAI_FORCE_PROMPT } = process.env ?? {};
|
||||||
if (OPENROUTER_API_KEY && !this.azure) {
|
if (OPENROUTER_API_KEY && !this.azure) {
|
||||||
|
|
@ -146,7 +146,7 @@ class OpenAIClient extends BaseClient {
|
||||||
const { model } = this.modelOptions;
|
const { model } = this.modelOptions;
|
||||||
|
|
||||||
this.isChatCompletion =
|
this.isChatCompletion =
|
||||||
o1Pattern.test(model) || model.includes('gpt') || this.useOpenRouter || !!reverseProxy;
|
omniPattern.test(model) || model.includes('gpt') || this.useOpenRouter || !!reverseProxy;
|
||||||
this.isChatGptModel = this.isChatCompletion;
|
this.isChatGptModel = this.isChatCompletion;
|
||||||
if (
|
if (
|
||||||
model.includes('text-davinci') ||
|
model.includes('text-davinci') ||
|
||||||
|
|
@ -475,7 +475,7 @@ class OpenAIClient extends BaseClient {
|
||||||
promptPrefix = this.augmentedPrompt + promptPrefix;
|
promptPrefix = this.augmentedPrompt + promptPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promptPrefix && this.isO1Model !== true) {
|
if (promptPrefix && this.isOmni !== true) {
|
||||||
promptPrefix = `Instructions:\n${promptPrefix.trim()}`;
|
promptPrefix = `Instructions:\n${promptPrefix.trim()}`;
|
||||||
instructions = {
|
instructions = {
|
||||||
role: 'system',
|
role: 'system',
|
||||||
|
|
@ -503,7 +503,7 @@ class OpenAIClient extends BaseClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** EXPERIMENTAL */
|
/** EXPERIMENTAL */
|
||||||
if (promptPrefix && this.isO1Model === true) {
|
if (promptPrefix && this.isOmni === true) {
|
||||||
const lastUserMessageIndex = payload.findLastIndex((message) => message.role === 'user');
|
const lastUserMessageIndex = payload.findLastIndex((message) => message.role === 'user');
|
||||||
if (lastUserMessageIndex !== -1) {
|
if (lastUserMessageIndex !== -1) {
|
||||||
payload[
|
payload[
|
||||||
|
|
@ -1200,7 +1200,7 @@ ${convo}
|
||||||
opts.defaultHeaders = { ...opts.defaultHeaders, 'api-key': this.apiKey };
|
opts.defaultHeaders = { ...opts.defaultHeaders, 'api-key': this.apiKey };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isO1Model === true && modelOptions.max_tokens != null) {
|
if (this.isOmni === true && modelOptions.max_tokens != null) {
|
||||||
modelOptions.max_completion_tokens = modelOptions.max_tokens;
|
modelOptions.max_completion_tokens = modelOptions.max_tokens;
|
||||||
delete modelOptions.max_tokens;
|
delete modelOptions.max_tokens;
|
||||||
}
|
}
|
||||||
|
|
@ -1280,13 +1280,13 @@ ${convo}
|
||||||
let streamResolve;
|
let streamResolve;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.isO1Model === true &&
|
this.isOmni === true &&
|
||||||
(this.azure || /o1(?!-(?:mini|preview)).*$/.test(modelOptions.model)) &&
|
(this.azure || /o1(?!-(?:mini|preview)).*$/.test(modelOptions.model)) &&
|
||||||
modelOptions.stream
|
modelOptions.stream
|
||||||
) {
|
) {
|
||||||
delete modelOptions.stream;
|
delete modelOptions.stream;
|
||||||
delete modelOptions.stop;
|
delete modelOptions.stop;
|
||||||
} else if (!this.isO1Model && modelOptions.reasoning_effort != null) {
|
} else if (!this.isOmni && modelOptions.reasoning_effort != null) {
|
||||||
delete modelOptions.reasoning_effort;
|
delete modelOptions.reasoning_effort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1366,7 +1366,7 @@ ${convo}
|
||||||
for await (const chunk of stream) {
|
for await (const chunk of stream) {
|
||||||
// Add finish_reason: null if missing in any choice
|
// Add finish_reason: null if missing in any choice
|
||||||
if (chunk.choices) {
|
if (chunk.choices) {
|
||||||
chunk.choices.forEach(choice => {
|
chunk.choices.forEach((choice) => {
|
||||||
if (!('finish_reason' in choice)) {
|
if (!('finish_reason' in choice)) {
|
||||||
choice.finish_reason = null;
|
choice.finish_reason = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,9 @@ const tokenValues = Object.assign(
|
||||||
'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 },
|
||||||
|
'o3-mini': { prompt: 1.1, completion: 4.4 },
|
||||||
|
'o1-mini': { prompt: 1.1, completion: 4.4 },
|
||||||
'o1-preview': { prompt: 15, completion: 60 },
|
'o1-preview': { prompt: 15, completion: 60 },
|
||||||
'o1-mini': { prompt: 3, completion: 12 },
|
|
||||||
o1: { prompt: 15, completion: 60 },
|
o1: { prompt: 15, completion: 60 },
|
||||||
'gpt-4o-mini': { prompt: 0.15, completion: 0.6 },
|
'gpt-4o-mini': { prompt: 0.15, completion: 0.6 },
|
||||||
'gpt-4o': { prompt: 2.5, completion: 10 },
|
'gpt-4o': { prompt: 2.5, completion: 10 },
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const z = require('zod');
|
||||||
const { EModelEndpoint } = require('librechat-data-provider');
|
const { EModelEndpoint } = require('librechat-data-provider');
|
||||||
|
|
||||||
const openAIModels = {
|
const openAIModels = {
|
||||||
|
'o3-mini': 195000, // -5000 from max
|
||||||
o1: 195000, // -5000 from max
|
o1: 195000, // -5000 from max
|
||||||
'o1-mini': 127500, // -500 from max
|
'o1-mini': 127500, // -500 from max
|
||||||
'o1-preview': 127500, // -500 from max
|
'o1-preview': 127500, // -500 from max
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ type EndpointIcon = {
|
||||||
|
|
||||||
function getOpenAIColor(_model: string | null | undefined) {
|
function getOpenAIColor(_model: string | null | undefined) {
|
||||||
const model = _model?.toLowerCase() ?? '';
|
const model = _model?.toLowerCase() ?? '';
|
||||||
if (model && /\bo1\b/i.test(model)) {
|
if (model && /\b(o1|o3)\b/i.test(model)) {
|
||||||
return '#000000';
|
return '#000000';
|
||||||
}
|
}
|
||||||
return model.includes('gpt-4') ? '#AB68FF' : '#19C37D';
|
return model.includes('gpt-4') ? '#AB68FF' : '#19C37D';
|
||||||
|
|
|
||||||
|
|
@ -778,9 +778,9 @@ export const supportsBalanceCheck = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const visionModels = [
|
export const visionModels = [
|
||||||
'o1',
|
|
||||||
'gpt-4o',
|
'gpt-4o',
|
||||||
'gpt-4o-mini',
|
'gpt-4o-mini',
|
||||||
|
'o1',
|
||||||
'gpt-4-turbo',
|
'gpt-4-turbo',
|
||||||
'gpt-4-vision',
|
'gpt-4-vision',
|
||||||
'llava',
|
'llava',
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,8 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
|
||||||
return modelLabel;
|
return modelLabel;
|
||||||
} else if (model && /\bo1\b/i.test(model)) {
|
} else if (model && /\bo1\b/i.test(model)) {
|
||||||
return 'o1';
|
return 'o1';
|
||||||
|
} else if (model && /\bo3\b/i.test(model)) {
|
||||||
|
return 'o3';
|
||||||
} else if (model && model.includes('gpt-3')) {
|
} else if (model && model.includes('gpt-3')) {
|
||||||
return 'GPT-3.5';
|
return 'GPT-3.5';
|
||||||
} else if (model && model.includes('gpt-4o')) {
|
} else if (model && model.includes('gpt-4o')) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue