Files
mc-bot-town/nodejs/controller/ai.js
T
2026-07-12 17:26:59 -04:00

105 lines
3.3 KiB
JavaScript

'use strict';
const conf = require('../conf');
/**
* Ai plugin — thin shim.
*
* The real work (LLM provider, poll timer, tool registry, response processing)
* lives in AiManager. This class exists only for compatibility with CJbot's
* plugin system: pluginAdd/pluginLoad/pluginUnload, the .ai chat command,
* and the trade plugin's _expectingTradeWindow flag.
*
* Only ONE bot should load this plugin. The config key `ai.faceBot` names it.
*/
class Ai {
constructor(args) {
this.bot = args.bot;
// Extract config — same destructure as the old Ai class
const { bot: _bot, promptName, prompCustom, intervalLength, interval, ...configProps } = args;
this.promptName = promptName;
this.prompCustom = prompCustom || '';
this.botConfig = args.botConfig || configProps || {};
}
async init() {
const { getInstance } = require('./ai/manager');
const manager = getInstance();
// If manager is already active on another bot, that's a config conflict
if (manager.isActive && manager.faceBotName !== this.bot.name) {
console.warn(`Ai: manager already running on ${manager.faceBotName} — ignoring init on ${this.bot.name}`);
console.warn(`Ai: shutdown the existing Ai plugin first, or change ai.faceBot in config`);
return;
}
// If already active on THIS bot, this is a reload (e.g. .ai command)
if (manager.isActive && manager.faceBotName === this.bot.name) {
await manager.reloadPrompt(this.promptName, this.prompCustom);
return;
}
// Fresh init
await manager.init(this.bot, this._getConfig());
this.bot._aiControlsTrade = true;
console.log(`Ai: ${this.bot.name} is the face bot`);
}
async unload() {
const { getInstance } = require('./ai/manager');
const manager = getInstance();
if (manager.faceBotName === this.bot.name) {
await manager.shutdown();
}
delete this.bot._aiControlsTrade;
console.log(`Ai: unloaded from ${this.bot.name}`);
return true;
}
_getConfig() {
return { ...conf.ai, ...this.botConfig };
}
// ========================================
// Backward-compat proxies
// These are accessed by trade.js and the web UI
// ========================================
get _expectingTradeWindow() {
const { getInstance } = require('./ai/manager');
return getInstance()._expectingTradeWindow;
}
set _expectingTradeWindow(val) {
const { getInstance } = require('./ai/manager');
getInstance()._expectingTradeWindow = val;
}
get _active() {
const { getInstance } = require('./ai/manager');
return getInstance().isActive;
}
get memoryDB() {
const { getInstance } = require('./ai/manager');
return getInstance()._memoryDB;
}
get intervalLength() {
return this._getConfig().interval || 10;
}
get provider() {
const { getInstance } = require('./ai/manager');
return getInstance()._provider;
}
}
// Web UI support — unchanged pattern, but routes now use the manager internally
const AiWeb = require('./ai/web');
Ai.createRouter = AiWeb.createRouter;
Ai.webUI = AiWeb.webUI;
module.exports = Ai;