| "use strict"; |
| |
| var __importDefault = (this && this.__importDefault) || function (mod) { |
| return (mod && mod.__esModule) ? mod : { "default": mod }; |
| }; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.Bot = void 0; |
| |
| |
| |
| const chatgpt_1 = require("chatgpt"); |
| const p_retry_1 = __importDefault(require("p-retry")); |
| const options_1 = require("./options"); |
| const limits_1 = require("./limits"); |
| const logInfo = console.log; |
| const logWarning = console.warn; |
| const logError = console.error; |
| |
| const setFailed = (msg) => { |
| console.error(msg); |
| process.exit(1); |
| }; |
| class Bot { |
| api = null; |
| options; |
| aiOptions; |
| currentModel; |
| fallbackModels; |
| constructor(options, aiOptions) { |
| this.options = options; |
| this.aiOptions = aiOptions; |
| this.currentModel = aiOptions.model; |
| |
| if (options_1.Options.HEAVY_MODELS.includes(this.currentModel)) { |
| this.fallbackModels = [...options_1.Options.HEAVY_MODELS]; |
| } |
| else { |
| this.fallbackModels = [...options_1.Options.LIGHT_MODELS]; |
| } |
| |
| this.fallbackModels = this.fallbackModels.filter(m => m !== this.currentModel); |
| this.initClient(); |
| } |
| initClient() { |
| const apiKey = process.env.GROQ_API_KEY || process.env.AI_API_KEY; |
| if (apiKey) { |
| const currentDate = new Date().toISOString().split('T')[0]; |
| const limits = new limits_1.TokenLimits(this.currentModel); |
| const systemMessage = `${this.options.systemMessage} |
| Knowledge cutoff: ${limits.knowledgeCutOff} |
| Current date: ${currentDate} |
| IMPORTANT: Entire response must be in ISO code: ${this.options.language} |
| `; |
| this.api = new chatgpt_1.ChatGPTAPI({ |
| apiBaseUrl: this.options.apiBaseUrl, |
| systemMessage, |
| apiKey, |
| apiOrg: process.env.AI_API_ORG || undefined, |
| debug: this.options.debug, |
| maxModelTokens: limits.maxTokens, |
| maxResponseTokens: limits.responseTokens, |
| completionParams: { |
| temperature: this.options.modelTemperature, |
| model: this.currentModel |
| } |
| }); |
| logInfo(`Initialized AI client with model: ${this.currentModel}`); |
| } |
| else { |
| throw new Error("Missing 'GROQ_API_KEY' or 'AI_API_KEY'"); |
| } |
| } |
| chat = async (message, ids) => { |
| let res = ['', {}]; |
| try { |
| res = await this.chat_(message, ids); |
| return res; |
| } |
| catch (e) { |
| if (e instanceof chatgpt_1.ChatGPTError) { |
| logWarning(`AI communication error: ${e.message}`); |
| } |
| return res; |
| } |
| }; |
| chat_ = async (message, ids) => { |
| const start = Date.now(); |
| if (!message) |
| return ['', {}]; |
| let response; |
| if (this.api != null) { |
| const opts = { |
| timeoutMs: this.options.timeoutMS |
| }; |
| if (ids.parentMessageId) { |
| opts.parentMessageId = ids.parentMessageId; |
| } |
| try { |
| response = await (0, p_retry_1.default)(async (attemptState) => { |
| try { |
| const result = await this.api.sendMessage(message, opts); |
| return result; |
| } |
| catch (e) { |
| if (e?.status === 429 && this.fallbackModels.length > 0) { |
| const nextModel = this.fallbackModels.shift(); |
| if (nextModel) { |
| logWarning(`Rate limit (429) hit for ${this.currentModel}. Switching to fallback: ${nextModel}`); |
| this.currentModel = nextModel; |
| this.initClient(); |
| } |
| } |
| throw e; |
| } |
| }, { |
| retries: this.options.retries, |
| onFailedAttempt: (err) => { |
| logInfo(`Attempt ${err.attemptNumber} failed. ${err.retriesLeft} retries left.`); |
| const errorResponse = err.response || err.status; |
| if (errorResponse === 429 && this.fallbackModels.length > 0) { |
| const nextModel = this.fallbackModels.shift(); |
| if (nextModel) { |
| logWarning(`Proactive switch to fallback model: ${nextModel} due to 429`); |
| this.currentModel = nextModel; |
| this.initClient(); |
| } |
| } |
| } |
| }); |
| } |
| catch (e) { |
| if (e instanceof chatgpt_1.ChatGPTError) { |
| logInfo(`AI Error: ${e.message} (Last model used: ${this.currentModel})`); |
| } |
| } |
| const end = Date.now(); |
| logInfo(`AI response time: ${end - start} ms`); |
| } |
| else { |
| setFailed('AI client is not initialized'); |
| } |
| let responseText = ''; |
| if (response != null) { |
| responseText = response.text; |
| } |
| const newIds = { |
| parentMessageId: response?.id, |
| conversationId: response?.conversationId |
| }; |
| return [responseText, newIds]; |
| }; |
| } |
| exports.Bot = Bot; |
| |