"use strict";
import MessageClient from "./message-client.js";
import ModerationClient from "./moderation-client.js";
import Memory from "./memory.js";
import moderator from "./moderator.js";
import {
validateCoolDownInSeconds,
validateEnableMessageLogging,
validateEnableModeration,
validateEnableSecurityInstructions,
validateFallbackMessage,
validateJailbreakConfidenceScore,
validateReplyConfidenceScore,
} from "./validator.js";
const DEFAULT_ENABLE_MODERATION = true;
const DEFAULT_ENABLE_MESSAGE_LOGGING = false;
const DEFAULT_MINIMUM_REPLY_CONFIDENCE_SCORE = 0.9;
const DEFAULT_MINIMUM_JAILBREAK_CONFIDENCE_SCORE = 0.7;
const DEFAULT_COOL_DOWN_IN_SECONDS = 15;
const DEFAULT_FALLBACK_MESSAGE =
"Sorry, I cannot provide a response to that message.";
const DEFAULT_ENABLE_SECURITY_INSTRUCTIONS = true;
let memory;
/**
* Register the Mineflayer ChatGPT plugin on a bot instance.
*
* @param {object} bot - Mineflayer bot instance.
*/
function chatgpt(bot) {
let messageClient;
let moderationClient;
let enableModeration;
let enableMessageLogging;
let minimumReplyConfidenceScore;
let minimumJailbreakConfidenceScore;
let coolDownInSeconds;
let fallbackMessage;
bot.chatgpt = {};
/**
* Configure the plugin instance.
*
* @param {object} [opts={}] - Plugin options.
* @param {string} opts.messageApiKey - API key for the chat completion endpoint. Can be a placeholder value when `messageBaseURL` points at a local LLM server (e.g. vMLX) that doesn't require authentication.
* @param {string} [opts.model='gpt-5.6'] - Chat completion model. The minimum supported OpenAI model is GPT-5.6.
* @param {string} [opts.moderationApiKey] - OpenAI API key used for moderation and jailbreak detection. Required when `enableModeration` is `true`.
* @param {string} [opts.messageBaseURL] - Base URL of the chat completion endpoint. Set this to use a local OpenAI-compatible LLM server (e.g. vMLX) instead of OpenAI.
* @param {number} [opts.minimumReplyConfidenceScore=0.9] - Minimum confidence required to accept a model reply.
* @param {number} [opts.minimumJailbreakConfidenceScore=0.7] - Minimum OpenAI Guardrails confidence required to flag a jailbreak attempt.
*/
bot.chatgpt.setConfig = (opts) => {
opts = opts || {};
enableModeration =
opts.enableModeration === undefined
? DEFAULT_ENABLE_MODERATION
: opts.enableModeration;
validateEnableModeration(enableModeration);
enableMessageLogging =
opts.enableMessageLogging === undefined
? DEFAULT_ENABLE_MESSAGE_LOGGING
: opts.enableMessageLogging;
validateEnableMessageLogging(enableMessageLogging);
minimumReplyConfidenceScore =
opts.minimumReplyConfidenceScore ??
DEFAULT_MINIMUM_REPLY_CONFIDENCE_SCORE;
validateReplyConfidenceScore(minimumReplyConfidenceScore);
minimumJailbreakConfidenceScore =
opts.minimumJailbreakConfidenceScore ??
DEFAULT_MINIMUM_JAILBREAK_CONFIDENCE_SCORE;
validateJailbreakConfidenceScore(minimumJailbreakConfidenceScore);
coolDownInSeconds =
opts.coolDownInSeconds === undefined
? DEFAULT_COOL_DOWN_IN_SECONDS
: opts.coolDownInSeconds;
validateCoolDownInSeconds(coolDownInSeconds);
fallbackMessage =
opts.fallbackMessage === undefined
? DEFAULT_FALLBACK_MESSAGE
: opts.fallbackMessage;
validateFallbackMessage(fallbackMessage);
opts.enableSecurityInstructions =
opts.enableSecurityInstructions === undefined
? DEFAULT_ENABLE_SECURITY_INSTRUCTIONS
: opts.enableSecurityInstructions;
validateEnableSecurityInstructions(opts.enableSecurityInstructions);
messageClient = new MessageClient(opts.messageApiKey, {
model: opts.model,
instructions: opts.instructions,
enableSecurityInstructions: opts.enableSecurityInstructions,
baseURL: opts.messageBaseURL,
});
if (enableModeration === true) {
moderationClient = new ModerationClient(opts.moderationApiKey);
}
memory = new Memory(opts.historySize);
};
/**
* Send a message through the plugin and return the final reply.
*
* @param {string} player - Player name or id.
* @param {string} message - Message to send.
* @returns {Promise<string>} Final reply text.
*/
bot.chatgpt.sendMessage = async (player, message) => {
try {
if (enableModeration === true) {
const moderatedOutbound = await moderator.moderateOutboundMessage(
moderationClient,
memory,
player,
message,
fallbackMessage,
coolDownInSeconds,
minimumJailbreakConfidenceScore,
);
if (moderatedOutbound.flagged) {
return moderatedOutbound.message;
}
message = moderatedOutbound.message;
}
const chatResult = await messageClient.chat(memory, player, message);
let reply = chatResult.reply;
const confidenceScore = chatResult.confidenceScore;
if (enableModeration === true) {
const moderatedInbound = await moderator.moderateInboundReply(
moderationClient,
reply,
fallbackMessage,
confidenceScore,
minimumReplyConfidenceScore,
);
reply = moderatedInbound.reply;
}
if (enableMessageLogging === true) {
console.log(`Player ${player} received a reply from ChatGPT: ${reply}`);
}
return reply;
} catch (error) {
console.error(`An unexpected error has occurred: ${error.message}`);
throw error;
}
};
}
const exports = {
chatgpt: chatgpt,
};
export { exports as default };