diff --git a/src/backend/src/modules/puterai/AIChatService.js b/src/backend/src/modules/puterai/AIChatService.js index 56857c30..e995947d 100644 --- a/src/backend/src/modules/puterai/AIChatService.js +++ b/src/backend/src/modules/puterai/AIChatService.js @@ -406,16 +406,46 @@ class AIChatService extends BaseService { // Updated: Check usage and get a boolean result instead of throwing error const svc_cost = this.services.get('cost'); - const usageAllowed = await svc_cost.get_funding_allowed(); - + const available = await svc_cost.get_available_amount(); + const model_input_cost = this.detail_model_map[model_used].cost.input; + const model_output_cost = this.detail_model_map[model_used].cost.output; + const text = Messages.extract_text(parameters.messages); + const approximate_input_cost = text.length / 4 * model_input_cost; + const usageAllowed = await svc_cost.get_funding_allowed({ + available, + minimum: approximate_input_cost, + }); + // Handle usage limits reached case + this.log.noticeme('DEBUGGING VALUES', { + messages: parameters.messages, + text, + available, + model_input_cost, + model_output_cost, + approximate_input_cost, + usageAllowed, + }) if ( !usageAllowed ) { - // The check_usage_ method has already updated the intended_service to 'usage-limited-chat' + // The check_usage_ method has eady updated the intended_service to 'usage-limited-chat' service_used = 'usage-limited-chat'; model_used = 'usage-limited'; // Update intended_service to match service_used intended_service = service_used; } + + const max_allowed_output_amount = + available - approximate_input_cost; + + const max_allowed_output_tokens = + max_allowed_output_amount / model_output_cost; + + parameters.max_tokens = Math.min( + parameters.max_tokens ?? Number.POSITIVE_INFINITY, + max_allowed_output_tokens, + ); + + this.log.noticeme('AI PARAMETERS', parameters); try { ret = await svc_driver.call_new_({ diff --git a/src/backend/src/modules/puterai/FakeChatService.js b/src/backend/src/modules/puterai/FakeChatService.js index af1b1def..895bebeb 100644 --- a/src/backend/src/modules/puterai/FakeChatService.js +++ b/src/backend/src/modules/puterai/FakeChatService.js @@ -100,7 +100,7 @@ class FakeChatService extends BaseService { * @param {string} params.model - The model to use ('fake', 'costly', or 'abuse') * @returns {Object} A simulated chat completion response with Lorem Ipsum content */ - async complete ({ messages, stream, model }) { + async complete ({ messages, stream, model, max_tokens }) { const { LoremIpsum } = require('lorem-ipsum'); const li = new LoremIpsum({ sentencesPerParagraph: { @@ -137,7 +137,8 @@ class FakeChatService extends BaseService { } // Generate random output token count between 50 and 200 - outputTokens = Math.floor(Math.random() * 150) + 50; + outputTokens = Math.floor(Math.min((Math.random() * 150)+50, max_tokens)); + // outputTokens = Math.floor(Math.random() * 150) + 50; } // Generate the response text diff --git a/src/backend/src/services/drivers/CostService.js b/src/backend/src/services/drivers/CostService.js index a7ffe8b3..254ee76d 100644 --- a/src/backend/src/services/drivers/CostService.js +++ b/src/backend/src/services/drivers/CostService.js @@ -28,6 +28,11 @@ class CostService extends BaseService { } async get_funding_allowed (options = {}) { + return (options.available ?? await this.get_available_amount()) + >= (options.minimum ?? 100); + } + + async get_available_amount () { const cost_uuid = this.modules.uuidv4(); const svc_event = this.services.get('event'); const event = { @@ -36,11 +41,8 @@ class CostService extends BaseService { cost_uuid, }; await svc_event.emit('credit.check-available', event); - - // specified minimum or 1/10th of a cent - const minimum = options.minimum ?? 100; - return event.available >= minimum; + return event.available; } async record_cost ({ cost }) { const svc_event = this.services.get('event');