Large Transaction Update

This commit is contained in:
Logan Cusano
2023-02-27 00:20:54 -05:00
parent 0c4fee091e
commit 384dd7011f
6 changed files with 79 additions and 31 deletions

View File

@@ -37,7 +37,7 @@ module.exports = {
const maxTokens = interaction.options.getNumber('tokens') ?? undefined; const maxTokens = interaction.options.getNumber('tokens') ?? undefined;
const discordAccountId = interaction.member.id; const discordAccountId = interaction.member.id;
try { try {
submitTextPromptTransaction(promptText, temperature, maxTokens, discordAccountId, async (err, result) => { submitTextPromptTransaction(promptText, temperature, maxTokens, discordAccountId, interaction, this, async (err, result) => {
if (err) throw err; if (err) throw err;
const gptEmbed = new EmmeliaEmbedBuilder() const gptEmbed = new EmmeliaEmbedBuilder()

View File

@@ -42,7 +42,7 @@ module.exports = {
const size = interaction.options.getString('size') ?? undefined; const size = interaction.options.getString('size') ?? undefined;
const discordAccountId = interaction.member.id; const discordAccountId = interaction.member.id;
try { try {
submitImagePromptTransaction(promptText, discordAccountId, images, size, async (err, imageResults) => { submitImagePromptTransaction(promptText, discordAccountId, images, size, interaction, this, async (err, imageResults) => {
if (err) throw err; if (err) throw err;
log.DEBUG("Image Results: ", imageResults) log.DEBUG("Image Results: ", imageResults)
@@ -51,7 +51,7 @@ module.exports = {
.setColor(0x0099FF) .setColor(0x0099FF)
.setTitle(`New Image Result`) .setTitle(`New Image Result`)
.setDescription(`${interaction.member.user} sent the prompt: '${promptText}'`) .setDescription(`${interaction.member.user} sent the prompt: '${promptText}'`)
.addFields({ name: 'Tokens Used', value: `${this.defaultTokenUsage}`, inline: true }) .addFields({ name: 'Tokens Used', value: `${imageResults.totalTokens}`, inline: true })
const imagesInResult = Array(imageResults.results.data).length const imagesInResult = Array(imageResults.results.data).length

View File

@@ -3,6 +3,7 @@ const log = new DebugBuilder("server", "openAiController");
const crypto = require('crypto') const crypto = require('crypto')
const { createTransaction } = require("./transactionController"); const { createTransaction } = require("./transactionController");
const { authorizeTokenUsage } = require("../middleware/balanceAuthorization");
const { encode } = require("gpt-3-encoder") const { encode } = require("gpt-3-encoder")
const { Configuration, OpenAIApi } = require('openai'); const { Configuration, OpenAIApi } = require('openai');
@@ -86,7 +87,7 @@ async function getTextGeneration(_prompt, callback, { _model = "text-davinci-003
* @param {*} param1 Default parameters can be modified * @param {*} param1 Default parameters can be modified
* @returns * @returns
*/ */
exports.submitTextPromptTransaction = async (prompt, temperature, max_tokens, discord_account_id, callback) => { exports.submitTextPromptTransaction = async (prompt, temperature, max_tokens, discord_account_id, interaction, command, callback) => {
getTextGeneration(prompt, (err, gptResult) => { getTextGeneration(prompt, (err, gptResult) => {
if (err) callback(err, undefined); if (err) callback(err, undefined);
@@ -116,29 +117,59 @@ exports.submitTextPromptTransaction = async (prompt, temperature, max_tokens, di
* @param {*} image_size The size of the image ["256x256" | "512x512" | "1024x1024"] * @param {*} image_size The size of the image ["256x256" | "512x512" | "1024x1024"]
* @param {*} callback * @param {*} callback
*/ */
exports.submitImagePromptTransaction = async (prompt, discord_account_id, images_to_generate, image_size, callback) => { exports.submitImagePromptTransaction = async (prompt, discord_account_id, images_to_generate, image_size, interaction, command, callback) => {
let pricePerImage = 800;
log.DEBUG(image_size)
switch(image_size){
case "1024x1024":
log.DEBUG("1024 selected");
pricePerImage = 1000;
break;
case "512x512":
pricePerImage = 900;
log.DEBUG("512 selected");
break;
case "256x256":
log.DEBUG("256 selected");
pricePerImage = 800;
break;
default:
log.DEBUG("256px defaulted");
pricePerImage = 800;
break;
}
if (!images_to_generate) images_to_generate = 1;
if (!image_size) images_to_generate = "256x256";
getImageGeneration(prompt, { totalTokensToBeUsed = pricePerImage * images_to_generate;
_image_size: image_size,
_images_to_generate: images_to_generate
}, (err, dalleResult) => {
if (err) callback(err, undefined);
// TODO - Use the pricing table to calculate discord tokens log.DEBUG("Total tokens to be used", totalTokensToBeUsed, pricePerImage, images_to_generate);
log.DEBUG("DALL-E Result", dalleResult);
const discordTokensUsed = 100;
const providerTokensUsed = 100;
const dalleResultHash = crypto.createHash('sha1').update(JSON.stringify({ discord_account_id : prompt, images_to_generate: image_size })).digest('hex')
if (dalleResult){ authorizeTokenUsage(interaction, command, totalTokensToBeUsed, (isAuthorized) => {
createTransaction(dalleResultHash, discord_account_id, discordTokensUsed, providerTokensUsed, 2, async (err, transactionResult) => { if (isAuthorized) {
getImageGeneration(prompt, {
_image_size: image_size,
_images_to_generate: images_to_generate
}, (err, dalleResult) => {
if (err) callback(err, undefined); if (err) callback(err, undefined);
if (transactionResult){ // TODO - Use the pricing table to calculate discord tokens
log.DEBUG("Transaction Created: ", transactionResult); log.DEBUG("DALL-E Result", dalleResult);
callback(undefined, ({ results: dalleResult, totalTokens: discordTokensUsed}));
} const dalleResultHash = crypto.createHash('sha1').update(JSON.stringify({ discord_account_id : prompt, images_to_generate: image_size })).digest('hex')
});
} if (dalleResult){
}); createTransaction(dalleResultHash, discord_account_id, totalTokensToBeUsed, totalTokensToBeUsed, 2, async (err, transactionResult) => {
if (err) callback(err, undefined);
if (transactionResult){
log.DEBUG("Transaction Created: ", transactionResult);
callback(undefined, ({ results: dalleResult, totalTokens: totalTokensToBeUsed}));
}
});
}
});
}
})
} }

View File

@@ -20,7 +20,7 @@ module.exports = {
log.DEBUG(`${interaction.member.user} is running '${interaction.commandName}'`); log.DEBUG(`${interaction.member.user} is running '${interaction.commandName}'`);
await authorizeCommand(interaction, command, async () => { await authorizeCommand(interaction, command, async () => {
await authorizeTokenUsage(interaction, command, async () => { await authorizeTokenUsage(interaction, command, undefined, async () => {
try { try {
if (command.deferInitialReply) { if (command.deferInitialReply) {
try { try {

View File

@@ -186,6 +186,7 @@ exports.UserStorage = class UserStorage extends Storage {
*/ */
checkBalance(_tokensToBeUsed, _account_id, callback) { checkBalance(_tokensToBeUsed, _account_id, callback) {
if (!_account_id) return callback(new Error("Account not specified when checking account balance"), undefined); if (!_account_id) return callback(new Error("Account not specified when checking account balance"), undefined);
log.DEBUG("Tokens to verify against balance", _tokensToBeUsed, _account_id);
if (!_tokensToBeUsed && !_tokensToBeUsed >= 0) return callback(new Error("Specified tokens are invalid when checking account balance"), undefined); if (!_tokensToBeUsed && !_tokensToBeUsed >= 0) return callback(new Error("Specified tokens are invalid when checking account balance"), undefined);
this.getRecordBy('account_id', _account_id, (err, record) => { this.getRecordBy('account_id', _account_id, (err, record) => {
if (err) return callback(err, undefined); if (err) return callback(err, undefined);
@@ -214,11 +215,11 @@ exports.UserStorage = class UserStorage extends Storage {
switch(_updateType){ switch(_updateType){
case "withdraw": case "withdraw":
// Code here to withdraw funds // Code here to withdraw funds
sqlQuery = `UPDATE ${this.dbTable} SET balance=balance-${_updateAmount} WHERE discord_account_id = ${_account_id};`; sqlQuery = `UPDATE ${this.dbTable} SET balance=balance-${_updateAmount} WHERE discord_account_id = ${_discord_account_id};`;
break; break;
case "deposit": case "deposit":
// Code here to withdraw funds // Code here to withdraw funds
sqlQuery = `UPDATE ${this.dbTable} SET balance=balance+${_updateAmount} WHERE discord_account_id = ${_account_id};`; sqlQuery = `UPDATE ${this.dbTable} SET balance=balance+${_updateAmount} WHERE discord_account_id = ${_discord_account_id};`;
break; break;
default: default:
log.ERROR('Update type not valid: ', _updateType); log.ERROR('Update type not valid: ', _updateType);

View File

@@ -12,13 +12,29 @@ const {
welcomeResponse welcomeResponse
} = require("../controllers/accountController"); } = require("../controllers/accountController");
exports.authorizeTokenUsage = async (interaction, command, next) => { /**
* Authorize a transaction amount for an account
*
* @param {*} interaction
* @param {*} command
* @param {undefined|number} _tokens The amount of tokens to authorize, set to undefined if the value is in the interaction
* @param {*} next
* @returns
*/
exports.authorizeTokenUsage = async (interaction, command, _tokens = undefined, next) => {
log.DEBUG("Command requires tokens? ", command.isPrivileged) log.DEBUG("Command requires tokens? ", command.isPrivileged)
if(!command.requiresTokens) return next(true); if(!command.requiresTokens) return next(true);
if(!interaction.member && (!interaction.options.getNumber("tokens") || !command.defaultTokenUsage)) throw new Error("No member or tokens specified before attempting to authorize"); if(!interaction.member && (!_tokens || !interaction.options.getNumber("tokens") || !command.defaultTokenUsage)) throw new Error("No member or tokens specified before attempting to authorize");
const memberId = interaction.member.id; const memberId = interaction.member.id;
const tokensToBeUsed = interaction.options.getNumber("tokens") ?? command.defaultTokenUsage var tokensToBeUsed;
if (!_tokens || _tokens && isNaN(_tokens)){
if (interaction.options.getNumber("tokens")) tokensToBeUsed = interaction.options.getNumber("tokens");
else tokensToBeUsed = command.defaultTokenUsage;
}
else tokensToBeUsed = _tokens;
log.DEBUG(`Authorizing ${memberId} for a purchase worth ${tokensToBeUsed} tokens`) log.DEBUG(`Authorizing ${memberId} for a purchase worth ${tokensToBeUsed} tokens`)
log.DEBUG("Checking for account associated with discord ID: ", memberId); log.DEBUG("Checking for account associated with discord ID: ", memberId);
await checkForAccount(memberId, async (err, results) => { await checkForAccount(memberId, async (err, results) => {