mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-22 02:14:10 +01:00
🤖 feat: Gemini 3.1 Pricing and Context Window (#11884)
- Added support for the new Gemini 3.1 models, including 'gemini-3.1-pro-preview' and 'gemini-3.1-pro-preview-customtools'. - Updated pricing logic to apply standard and premium rates based on token usage thresholds for the new models. - Enhanced tests to validate pricing behavior for both standard and premium scenarios. - Modified configuration files to include Gemini 3.1 models in the default model lists and token value mappings. - Updated environment example file to reflect the new model options.
This commit is contained in:
parent
a103ce72b4
commit
7a1d2969b8
8 changed files with 450 additions and 2 deletions
|
|
@ -878,6 +878,135 @@ describe('spendTokens', () => {
|
|||
expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
|
||||
});
|
||||
|
||||
it('should charge standard rates for gemini-3.1-pro-preview when prompt tokens are below threshold', async () => {
|
||||
const initialBalance = 100000000;
|
||||
await Balance.create({
|
||||
user: userId,
|
||||
tokenCredits: initialBalance,
|
||||
});
|
||||
|
||||
const model = 'gemini-3.1-pro-preview';
|
||||
const promptTokens = 100000;
|
||||
const completionTokens = 500;
|
||||
|
||||
const txData = {
|
||||
user: userId,
|
||||
conversationId: 'test-gemini31-standard-pricing',
|
||||
model,
|
||||
context: 'test',
|
||||
balance: { enabled: true },
|
||||
};
|
||||
|
||||
await spendTokens(txData, { promptTokens, completionTokens });
|
||||
|
||||
const expectedCost =
|
||||
promptTokens * tokenValues['gemini-3.1'].prompt +
|
||||
completionTokens * tokenValues['gemini-3.1'].completion;
|
||||
|
||||
const balance = await Balance.findOne({ user: userId });
|
||||
expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
|
||||
});
|
||||
|
||||
it('should charge premium rates for gemini-3.1-pro-preview when prompt tokens exceed threshold', async () => {
|
||||
const initialBalance = 100000000;
|
||||
await Balance.create({
|
||||
user: userId,
|
||||
tokenCredits: initialBalance,
|
||||
});
|
||||
|
||||
const model = 'gemini-3.1-pro-preview';
|
||||
const promptTokens = 250000;
|
||||
const completionTokens = 500;
|
||||
|
||||
const txData = {
|
||||
user: userId,
|
||||
conversationId: 'test-gemini31-premium-pricing',
|
||||
model,
|
||||
context: 'test',
|
||||
balance: { enabled: true },
|
||||
};
|
||||
|
||||
await spendTokens(txData, { promptTokens, completionTokens });
|
||||
|
||||
const expectedCost =
|
||||
promptTokens * premiumTokenValues['gemini-3.1'].prompt +
|
||||
completionTokens * premiumTokenValues['gemini-3.1'].completion;
|
||||
|
||||
const balance = await Balance.findOne({ user: userId });
|
||||
expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
|
||||
});
|
||||
|
||||
it('should charge premium rates for gemini-3.1-pro-preview-customtools when prompt tokens exceed threshold', async () => {
|
||||
const initialBalance = 100000000;
|
||||
await Balance.create({
|
||||
user: userId,
|
||||
tokenCredits: initialBalance,
|
||||
});
|
||||
|
||||
const model = 'gemini-3.1-pro-preview-customtools';
|
||||
const promptTokens = 250000;
|
||||
const completionTokens = 500;
|
||||
|
||||
const txData = {
|
||||
user: userId,
|
||||
conversationId: 'test-gemini31-customtools-premium',
|
||||
model,
|
||||
context: 'test',
|
||||
balance: { enabled: true },
|
||||
};
|
||||
|
||||
await spendTokens(txData, { promptTokens, completionTokens });
|
||||
|
||||
const expectedCost =
|
||||
promptTokens * premiumTokenValues['gemini-3.1'].prompt +
|
||||
completionTokens * premiumTokenValues['gemini-3.1'].completion;
|
||||
|
||||
const balance = await Balance.findOne({ user: userId });
|
||||
expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
|
||||
});
|
||||
|
||||
it('should charge premium rates for structured gemini-3.1 tokens when total input exceeds threshold', async () => {
|
||||
const initialBalance = 100000000;
|
||||
await Balance.create({
|
||||
user: userId,
|
||||
tokenCredits: initialBalance,
|
||||
});
|
||||
|
||||
const model = 'gemini-3.1-pro-preview';
|
||||
const txData = {
|
||||
user: userId,
|
||||
conversationId: 'test-gemini31-structured-premium',
|
||||
model,
|
||||
context: 'test',
|
||||
balance: { enabled: true },
|
||||
};
|
||||
|
||||
const tokenUsage = {
|
||||
promptTokens: {
|
||||
input: 200000,
|
||||
write: 10000,
|
||||
read: 5000,
|
||||
},
|
||||
completionTokens: 1000,
|
||||
};
|
||||
|
||||
const result = await spendStructuredTokens(txData, tokenUsage);
|
||||
|
||||
const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
|
||||
const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
|
||||
const writeRate = getCacheMultiplier({ model, cacheType: 'write' });
|
||||
const readRate = getCacheMultiplier({ model, cacheType: 'read' });
|
||||
|
||||
const expectedPromptCost =
|
||||
tokenUsage.promptTokens.input * premiumPromptRate +
|
||||
tokenUsage.promptTokens.write * writeRate +
|
||||
tokenUsage.promptTokens.read * readRate;
|
||||
const expectedCompletionCost = tokenUsage.completionTokens * premiumCompletionRate;
|
||||
|
||||
expect(result.prompt.prompt).toBeCloseTo(-expectedPromptCost, 0);
|
||||
expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
|
||||
});
|
||||
|
||||
it('should not apply premium pricing to non-premium models regardless of prompt size', async () => {
|
||||
const initialBalance = 100000000;
|
||||
await Balance.create({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue