104 lines
3.7 KiB
JavaScript
104 lines
3.7 KiB
JavaScript
// states/HandleChat.js
|
||
const path = require('path');
|
||
const fs = require('fs');
|
||
const { getLastChat, getBot, getDB, setActiveTask, clearActiveTask } = require('../core/context');
|
||
const { logChatMessage } = require('../memory/chat');
|
||
const { chatWithAI } = require('../lib/ai-helper');
|
||
const config = require('../config.json');
|
||
|
||
module.exports = async function HandleChat() {
|
||
const bot = getBot();
|
||
const db = getDB();
|
||
const { username, message } = getLastChat();
|
||
const msg = message.toLowerCase();
|
||
|
||
console.log(`[STATE] HandleChat: ${message}`);
|
||
logChatMessage(db, username, message);
|
||
|
||
const taskDir = path.join(__dirname, '../bot-tasks');
|
||
const availableTasks = fs.readdirSync(taskDir)
|
||
.filter(f => f.endsWith('.js'))
|
||
.map(f => f.replace('.js', ''));
|
||
|
||
const matchedTask = availableTasks.find(task => msg.includes(task.replace(/-/g, ' ')));
|
||
|
||
if (matchedTask) {
|
||
try {
|
||
const task = require(path.join(taskDir, matchedTask));
|
||
setActiveTask(matchedTask);
|
||
bot.chat(`Okay, I’ll try to ${matchedTask.replace(/-/g, ' ')}.`);
|
||
await task(bot, db, bot.chat);
|
||
clearActiveTask();
|
||
return;
|
||
} catch (err) {
|
||
console.error(`[TASK ERROR] ${matchedTask}:`, err.message);
|
||
bot.chat(`I couldn't complete the task "${matchedTask}".`);
|
||
clearActiveTask();
|
||
return;
|
||
}
|
||
}
|
||
|
||
const prompt = `Player said: "${message}". What task name should I execute (like 'find-flower', 'move-items')? Reply only with the task name or "none".`;
|
||
const aiResponse = await chatWithAI(prompt, config.ai);
|
||
const aiTask = aiResponse.trim().toLowerCase().replace(/\s+/g, '-');
|
||
|
||
if (aiTask !== 'none') {
|
||
const taskPath = path.join(taskDir, `${aiTask}.js`);
|
||
|
||
if (!fs.existsSync(taskPath)) {
|
||
bot.chat(`I don’t know how to ${aiTask.replace(/-/g, ' ')} yet, learning now...`);
|
||
|
||
const templatePath = path.join(__dirname, '../bot-tasks/TaskTemplate.js');
|
||
if (fs.existsSync(templatePath)) {
|
||
let template = fs.readFileSync(templatePath, 'utf8');
|
||
template = template.replace(/task-template/g, aiTask);
|
||
fs.writeFileSync(taskPath, template);
|
||
console.log(`[AI] Task file generated from template: ${taskPath}`);
|
||
|
||
// Ask AI to overwrite it with real logic
|
||
const taskPrompt = `
|
||
You are a Mineflayer bot assistant. Generate a new Node.js module for this task:
|
||
|
||
Task name: "${aiTask}"
|
||
|
||
Use this exact export:
|
||
module.exports = async function(bot, db, say) { ... }
|
||
|
||
Use valid Mineflayer APIs. Do NOT use bot.inventory.find(). Use bot.inventory.items().
|
||
This task should do what the player just asked: "${message}"
|
||
|
||
Only return valid code. No markdown. No explanation.
|
||
`.trim();
|
||
|
||
const aiCode = await chatWithAI(taskPrompt, config.ai);
|
||
if (aiCode.includes('module.exports')) {
|
||
fs.writeFileSync(taskPath, aiCode.trim());
|
||
console.log(`[AI] Task file overwritten with AI code: ${taskPath}`);
|
||
} else {
|
||
console.warn(`[AI] Failed to get valid task code from model. Keeping the template.`);
|
||
}
|
||
} else {
|
||
bot.chat(`Template not found. Cannot learn the task.`);
|
||
return;
|
||
}
|
||
}
|
||
|
||
try {
|
||
const task = require(taskPath);
|
||
setActiveTask(aiTask);
|
||
await task(bot, db, bot.chat);
|
||
clearActiveTask();
|
||
return;
|
||
} catch (err) {
|
||
console.error(`[TASK ERROR - AI GENERATED] ${aiTask}:`, err.message);
|
||
bot.chat(`I tried to learn how to ${aiTask.replace(/-/g, ' ')}, but it didn’t work.`);
|
||
clearActiveTask();
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (msg.includes(bot.username.toLowerCase())) {
|
||
const response = await chatWithAI(message, config.ai);
|
||
bot.chat(response);
|
||
}
|
||
};
|