LibreChat/api/models/Transaction.js
Danny Avila a9d2d3fe40
🪙 feat: Assistants Token Balance & other improvements (#2114)
* chore: add assistants to supportsBalanceCheck

* feat(Transaction): getTransactions and refactor export of model

* refactor: use enum: ViolationTypes.TOKEN_BALANCE

* feat(assistants): check balance

* refactor(assistants): only add promptBuffer if new convo (for title), and remove endpoint definition

* refactor(assistants): Count tokens up to the current context window

* fix(Switcher): make Select list explicitly controlled

* feat(assistants): use assistant's default model when no model is specified instead of the last selected assistant, prevent assistant_id from being recorded in non-assistant endpoints

* chore(assistants/chat): import order

* chore: bump librechat-data-provider due to changes
2024-03-15 19:48:42 -04:00

72 lines
2.4 KiB
JavaScript

const mongoose = require('mongoose');
const { isEnabled } = require('../server/utils/handleText');
const transactionSchema = require('./schema/transaction');
const { getMultiplier } = require('./tx');
const Balance = require('./Balance');
const cancelRate = 1.15;
// Method to calculate and set the tokenValue for a transaction
transactionSchema.methods.calculateTokenValue = function () {
if (!this.valueKey || !this.tokenType) {
this.tokenValue = this.rawAmount;
}
const { valueKey, tokenType, model, endpointTokenConfig } = this;
const multiplier = getMultiplier({ valueKey, tokenType, model, endpointTokenConfig });
this.rate = multiplier;
this.tokenValue = this.rawAmount * multiplier;
if (this.context && this.tokenType === 'completion' && this.context === 'incomplete') {
this.tokenValue = Math.ceil(this.tokenValue * cancelRate);
this.rate *= cancelRate;
}
};
// Static method to create a transaction and update the balance
transactionSchema.statics.create = async function (transactionData) {
const Transaction = this;
const transaction = new Transaction(transactionData);
transaction.endpointTokenConfig = transactionData.endpointTokenConfig;
transaction.calculateTokenValue();
// Save the transaction
await transaction.save();
if (!isEnabled(process.env.CHECK_BALANCE)) {
return;
}
// Adjust the user's balance
const updatedBalance = await Balance.findOneAndUpdate(
{ user: transaction.user },
{ $inc: { tokenCredits: transaction.tokenValue } },
{ upsert: true, new: true },
).lean();
return {
rate: transaction.rate,
user: transaction.user.toString(),
balance: updatedBalance.tokenCredits,
[transaction.tokenType]: transaction.tokenValue,
};
};
const Transaction = mongoose.model('Transaction', transactionSchema);
/**
* Queries and retrieves transactions based on a given filter.
* @async
* @function getTransactions
* @param {Object} filter - MongoDB filter object to apply when querying transactions.
* @returns {Promise<Array>} A promise that resolves to an array of matched transactions.
* @throws {Error} Throws an error if querying the database fails.
*/
async function getTransactions(filter) {
try {
return await Transaction.find(filter).lean();
} catch (error) {
console.error('Error querying transactions:', error);
throw error;
}
}
module.exports = { Transaction, getTransactions };