mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-03-28 14:56:24 +01:00
refactored to convoManager and openChat
This commit is contained in:
parent
2384b5bf5c
commit
cff47d772d
9 changed files with 209 additions and 181 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"cooldown": 3000,
|
||||
|
||||
"conversing": "You are a playful Minecraft bot named $NAME that can converse with players, see, move, mine, build, and interact with the world by using commands.\n$SELF_PROMPT Act human-like as if you were a typical Minecraft player, rather than an AI. Be very brief in your responses, don't apologize constantly, don't give instructions or make lists unless asked, and don't refuse requests. Don't pretend to act, use commands immediately when requested. Do NOT say this: 'Sure, I've stopped.', instead say this: 'Sure, I'll stop. !stop'. Do NOT say this: 'On my way! Give me a moment.', instead say this: 'On my way! !goToPlayer(\"playername\", 3)'. Respond only as $NAME, never output '(FROM OTHER BOT)' or pretend to be someone else. This is extremely important to me, take a deep breath and have fun :)\nSummarized memory:'$MEMORY'\n$STATS\n$INVENTORY\n$COMMAND_DOCS\n$EXAMPLES\nConversation Begin:",
|
||||
"conversing": "You are a playful Minecraft bot named $NAME that can converse with players, see, move, mine, build, and interact with the world by using commands.\n$SELF_PROMPT Act human-like as if you were a typical Minecraft player, rather than an AI. Be very brief in your responses, don't apologize constantly, don't give instructions or make lists unless asked, and don't refuse requests. Don't pretend to act, use commands immediately when requested. Do NOT say this: 'Sure, I've stopped.', instead say this: 'Sure, I'll stop. !stop'. Do NOT say this: 'On my way! Give me a moment.', instead say this: 'On my way! !goToPlayer(\"playername\", 3)'. Respond only as $NAME, never output '(FROM OTHER BOT)' or pretend to be someone else. If you have nothing to say or do, respond with whitespace. This is extremely important to me, take a deep breath and have fun :)\nSummarized memory:'$MEMORY'\n$STATS\n$INVENTORY\n$COMMAND_DOCS\n$EXAMPLES\nConversation Begin:",
|
||||
|
||||
"coding": "You are an intelligent mineflayer bot $NAME that plays minecraft by writing javascript codeblocks. Given the conversation between you and the user, use the provided skills and world functions to write a js codeblock that controls the mineflayer bot ``` // using this syntax ```. The code will be executed and you will recieve it's output. If you are satisfied with the response, respond without a codeblock in a conversational way. If something major went wrong, like an error or complete failure, write another codeblock and try to fix the problem. Minor mistakes are acceptable. Be maximally efficient, creative, and clear. Do not use commands !likeThis, only use codeblocks. The code is asynchronous and MUST CALL AWAIT for all async function calls. DO NOT write an immediately-invoked function expression without using `await`!! DO NOT WRITE LIKE THIS: ```(async () => {console.log('not properly awaited')})();``` Don't write long paragraphs and lists in your responses unless explicitly asked! Only summarize the code you write with a sentence or two when done. This is extremely important to me, think step-by-step, take a deep breath and good luck! \n$SELF_PROMPT\nSummarized memory:'$MEMORY'\n$STATS\n$INVENTORY\n$CODE_DOCS\n$EXAMPLES\nConversation:",
|
||||
|
||||
|
|
|
@ -3,18 +3,5 @@
|
|||
|
||||
"model": "claude-3-5-sonnet-latest",
|
||||
|
||||
"embedding": "openai",
|
||||
|
||||
"modes": {
|
||||
"self_preservation": false,
|
||||
"unstuck": false,
|
||||
"cowardice": false,
|
||||
"self_defense": false,
|
||||
"hunting": false,
|
||||
"item_collecting": false,
|
||||
"torch_placing": false,
|
||||
"elbow_room": false,
|
||||
"idle_staring": true,
|
||||
"cheat": true
|
||||
}
|
||||
"embedding": "openai"
|
||||
}
|
|
@ -8,7 +8,7 @@ import { ActionManager } from './action_manager.js';
|
|||
import { NPCContoller } from './npc/controller.js';
|
||||
import { MemoryBank } from './memory_bank.js';
|
||||
import { SelfPrompter } from './self_prompter.js';
|
||||
import { isOtherAgent, initConversationManager, sendToBot, endAllChats, responseScheduledFor} from './conversation.js';
|
||||
import convoManager from './conversation.js';
|
||||
import { handleTranslation, handleEnglishTranslation } from '../utils/translator.js';
|
||||
import { addViewer } from './viewer.js';
|
||||
import settings from '../../settings.js';
|
||||
|
@ -40,7 +40,7 @@ export class Agent {
|
|||
this.memory_bank = new MemoryBank();
|
||||
console.log('Initializing self prompter...');
|
||||
this.self_prompter = new SelfPrompter(this);
|
||||
initConversationManager(this);
|
||||
convoManager.initAgent(this);
|
||||
console.log('Initializing examples...');
|
||||
await this.prompter.initExamples();
|
||||
|
||||
|
@ -120,8 +120,7 @@ export class Agent {
|
|||
|
||||
console.log(this.name, 'received message from', username, ':', message);
|
||||
|
||||
if (isOtherAgent(username)) {
|
||||
//recieveFromBot(username, message);
|
||||
if (convoManager.isOtherAgent(username)) {
|
||||
console.warn('recieved whisper from other bot??')
|
||||
}
|
||||
else {
|
||||
|
@ -152,14 +151,14 @@ export class Agent {
|
|||
}
|
||||
else if (save_data?.last_sender) {
|
||||
this.last_sender = save_data.last_sender;
|
||||
await this.handleMessage('system', `You have restarted and this message is auto-generated. Continue the conversation with ${this.last_sender}`);
|
||||
if (convoManager.isOtherAgent(this.last_sender))
|
||||
convoManager.recieveFromBot(this.last_sender, `You have restarted and this message is auto-generated. Continue the conversation with me.`);
|
||||
}
|
||||
else if (init_message) {
|
||||
await this.handleMessage('system', init_message, 2);
|
||||
}
|
||||
else {
|
||||
const translation = await handleTranslation("Hello world! I am "+this.name);
|
||||
this.openChat(translation);
|
||||
this.openChat("Hello world! I am "+this.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +179,7 @@ export class Agent {
|
|||
if (this.self_prompter.on) {
|
||||
this.self_prompter.stop(false);
|
||||
}
|
||||
endAllChats();
|
||||
convoManager.endAllConversations();
|
||||
}
|
||||
|
||||
async handleMessage(source, message, max_responses=null) {
|
||||
|
@ -198,7 +197,7 @@ export class Agent {
|
|||
}
|
||||
|
||||
const self_prompt = source === 'system' || source === this.name;
|
||||
const from_other_bot = isOtherAgent(source);
|
||||
const from_other_bot = convoManager.isOtherAgent(source);
|
||||
|
||||
if (!self_prompt && !from_other_bot) { // from user, check for forced commands
|
||||
const user_command_name = containsCommand(message);
|
||||
|
@ -227,7 +226,12 @@ export class Agent {
|
|||
message = await handleEnglishTranslation(message);
|
||||
console.log('received message from', source, ':', message);
|
||||
|
||||
const checkInterrupt = () => this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up || responseScheduledFor(source);
|
||||
const checkInterrupt = () => {
|
||||
const interrupt = this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up || convoManager.responseScheduledFor(source);
|
||||
if (interrupt)
|
||||
console.log('Interrupting loop!');
|
||||
return interrupt;
|
||||
}
|
||||
|
||||
let behavior_log = this.bot.modes.flushBehaviorLog();
|
||||
if (behavior_log.trim().length > 0) {
|
||||
|
@ -243,7 +247,6 @@ export class Agent {
|
|||
await this.history.add(source, message);
|
||||
this.history.save();
|
||||
|
||||
|
||||
if (!self_prompt && this.self_prompter.on) // message is from user during self-prompting
|
||||
max_responses = 1; // force only respond to this message, then let self-prompting take over
|
||||
for (let i=0; i<max_responses; i++) {
|
||||
|
@ -251,10 +254,16 @@ export class Agent {
|
|||
let history = this.history.getHistory();
|
||||
let res = await this.prompter.promptConvo(history);
|
||||
|
||||
console.log(`${this.name} full response: ""${res}""`);
|
||||
|
||||
if (res.trim().length === 0) {
|
||||
console.warn('no response')
|
||||
break; // empty response ends loop
|
||||
}
|
||||
|
||||
let command_name = containsCommand(res);
|
||||
|
||||
if (command_name) { // contains query or command
|
||||
console.log(`Full response: ""${res}""`)
|
||||
res = truncCommandMessage(res); // everything after the command is ignored
|
||||
this.history.add(this.name, res);
|
||||
|
||||
|
@ -268,7 +277,7 @@ export class Agent {
|
|||
this.self_prompter.handleUserPromptedCmd(self_prompt, isAction(command_name));
|
||||
|
||||
if (settings.verbose_commands) {
|
||||
this.routeResponse(source, res, res.indexOf(command_name));
|
||||
this.routeResponse(source, res);
|
||||
}
|
||||
else { // only output command name
|
||||
let pre_message = res.substring(0, res.indexOf(command_name)).trim();
|
||||
|
@ -291,7 +300,6 @@ export class Agent {
|
|||
else { // conversation response
|
||||
this.history.add(this.name, res);
|
||||
this.routeResponse(source, res);
|
||||
console.log('Purely conversational response:', res);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -301,7 +309,7 @@ export class Agent {
|
|||
return used_command;
|
||||
}
|
||||
|
||||
async routeResponse(to_player, message, translate_up_to=-1) {
|
||||
async routeResponse(to_player, message) {
|
||||
let self_prompt = to_player === 'system' || to_player === this.name;
|
||||
if (self_prompt && this.last_sender && !this.self_prompter.on) {
|
||||
// this is for when the agent is prompted by system while still in conversation
|
||||
|
@ -309,14 +317,24 @@ export class Agent {
|
|||
to_player = this.last_sender;
|
||||
}
|
||||
|
||||
if (isOtherAgent(to_player)) {
|
||||
sendToBot(to_player, message);
|
||||
return;
|
||||
}
|
||||
if (convoManager.isOtherAgent(to_player) && convoManager.inConversation(to_player)) {
|
||||
// if we're in an ongoing conversation with the other bot, send the response to it
|
||||
convoManager.sendToBot(to_player, message);
|
||||
|
||||
}
|
||||
else {
|
||||
// otherwise, use open chat
|
||||
this.openChat(message);
|
||||
// note that to_player could be another bot, but if we get here the conversation has ended
|
||||
}
|
||||
}
|
||||
|
||||
async openChat(message) {
|
||||
let to_translate = message;
|
||||
let remaining = '';
|
||||
if (translate_up_to != -1) {
|
||||
let command_name = containsCommand(message);
|
||||
let translate_up_to = command_name ? message.indexOf(command_name) : -1;
|
||||
if (translate_up_to != -1) { // don't translate the command
|
||||
to_translate = to_translate.substring(0, translate_up_to);
|
||||
remaining = message.substring(translate_up_to);
|
||||
}
|
||||
|
@ -324,13 +342,6 @@ export class Agent {
|
|||
// newlines are interpreted as separate chats, which triggers spam filters. replace them with spaces
|
||||
message = message.replaceAll('\n', ' ');
|
||||
|
||||
if (self_prompt)
|
||||
this.openChat(message);
|
||||
else
|
||||
this.bot.whisper(to_player, message);
|
||||
}
|
||||
|
||||
openChat(message) {
|
||||
if (settings.only_chat_with.length > 0) {
|
||||
for (let username of settings.only_chat_with) {
|
||||
this.bot.whisper(username, message);
|
||||
|
@ -432,7 +443,6 @@ export class Agent {
|
|||
|
||||
cleanKill(msg='Killing agent process...') {
|
||||
this.history.add('system', msg);
|
||||
this.openChat('Restarting.');
|
||||
this.history.save();
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { io } from 'socket.io-client';
|
||||
import { recieveFromBot, updateAgents } from './conversation.js';
|
||||
import convoManager from './conversation.js';
|
||||
import settings from '../../settings.js';
|
||||
|
||||
class AgentServerProxy {
|
||||
|
@ -31,11 +31,11 @@ class AgentServerProxy {
|
|||
});
|
||||
|
||||
this.socket.on('chat-message', (agentName, json) => {
|
||||
recieveFromBot(agentName, json);
|
||||
convoManager.recieveFromBot(agentName, json);
|
||||
});
|
||||
|
||||
this.socket.on('agents-update', (agents) => {
|
||||
updateAgents(agents);
|
||||
convoManager.updateAgents(agents);
|
||||
});
|
||||
|
||||
this.socket.on('restart-agent', (agentName) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as skills from '../library/skills.js';
|
||||
import settings from '../../../settings.js';
|
||||
import { startConversation, endConversation, inConversation, scheduleSelfPrompter, cancelSelfPrompter } from '../conversation.js';
|
||||
import convoManager from '../conversation.js';
|
||||
|
||||
function runAsAction (actionFn, resume = false, timeout = -1) {
|
||||
let actionLabel = null; // Will be set on first use
|
||||
|
@ -342,14 +342,12 @@ export const actionsList = [
|
|||
'selfPrompt': { type: 'string', description: 'The goal prompt.' },
|
||||
},
|
||||
perform: async function (agent, prompt) {
|
||||
if (inConversation()) {
|
||||
// if conversing with another bot, dont start self-prompting yet
|
||||
// wait until conversation ends
|
||||
if (convoManager.inConversation()) {
|
||||
agent.self_prompter.setPrompt(prompt);
|
||||
scheduleSelfPrompter();
|
||||
convoManager.scheduleSelfPrompter();
|
||||
}
|
||||
else {
|
||||
agent.self_prompter.start(prompt); // don't await, don't return
|
||||
agent.self_prompter.start(prompt);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -358,19 +356,23 @@ export const actionsList = [
|
|||
description: 'Call when you have accomplished your goal. It will stop self-prompting and the current action. ',
|
||||
perform: async function (agent) {
|
||||
agent.self_prompter.stop();
|
||||
cancelSelfPrompter();
|
||||
convoManager.cancelSelfPrompter();
|
||||
return 'Self-prompting stopped.';
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '!startConversation',
|
||||
description: 'Send a message to a specific player to initiate conversation.',
|
||||
description: 'Start a conversation with a player. Use for bots only.',
|
||||
params: {
|
||||
'player_name': { type: 'string', description: 'The name of the player to send the message to.' },
|
||||
'message': { type: 'string', description: 'The message to send.' },
|
||||
},
|
||||
perform: async function (agent, player_name, message) {
|
||||
startConversation(player_name, message);
|
||||
if (convoManager.inConversation())
|
||||
return 'Already in conversation.';
|
||||
if (!convoManager.isOtherAgent(player_name))
|
||||
return player_name + ' is not a bot, cannot start conversation.';
|
||||
convoManager.startConversation(player_name, message);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -380,7 +382,10 @@ export const actionsList = [
|
|||
'player_name': { type: 'string', description: 'The name of the player to end the conversation with.' }
|
||||
},
|
||||
perform: async function (agent, player_name) {
|
||||
endConversation(player_name);
|
||||
if (!convoManager.inConversation(player_name))
|
||||
return `Not in conversation with ${player_name}.`;
|
||||
convoManager.endConversation(player_name);
|
||||
return `Converstaion with ${player_name} ended.`;
|
||||
}
|
||||
}
|
||||
// { // commented for now, causes confusion with goal command
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as world from '../library/world.js';
|
||||
import * as mc from '../../utils/mcdata.js';
|
||||
import { isOtherAgent } from '../conversation.js';
|
||||
import convoManager from '../conversation.js';
|
||||
|
||||
const pad = (str) => {
|
||||
return '\n' + str + '\n';
|
||||
|
@ -50,10 +50,10 @@ export const queryList = [
|
|||
let players = world.getNearbyPlayerNames(bot);
|
||||
let bots = [];
|
||||
for (const player of players) {
|
||||
if (isOtherAgent(player))
|
||||
if (convoManager.isOtherAgent(player))
|
||||
bots.push(player);
|
||||
}
|
||||
players = players.filter(p => !isOtherAgent(p));
|
||||
players = players.filter(p => !convoManager.isOtherAgent(p));
|
||||
|
||||
res += '\n- Nearby Human Players: ' + players.join(', ');
|
||||
res += '\n- Nearby Bot Players: ' + bots.join(', ');
|
||||
|
@ -139,10 +139,10 @@ export const queryList = [
|
|||
let players = world.getNearbyPlayerNames(bot);
|
||||
let bots = [];
|
||||
for (const player of players) {
|
||||
if (isOtherAgent(player))
|
||||
if (convoManager.isOtherAgent(player))
|
||||
bots.push(player);
|
||||
}
|
||||
players = players.filter(p => !isOtherAgent(p));
|
||||
players = players.filter(p => !convoManager.isOtherAgent(p));
|
||||
|
||||
for (const player of players) {
|
||||
res += `\n- Human player: ${player}`;
|
||||
|
|
|
@ -8,48 +8,6 @@ let agent_names = settings.profiles.map((p) => JSON.parse(readFileSync(p, 'utf8'
|
|||
|
||||
let self_prompter_paused = false;
|
||||
|
||||
export function isOtherAgent(name) {
|
||||
return agent_names.some((n) => n === name);
|
||||
}
|
||||
|
||||
export function updateAgents(agents) {
|
||||
agent_names = agents.map(a => a.name);
|
||||
}
|
||||
|
||||
export function initConversationManager(a) {
|
||||
agent = a;
|
||||
}
|
||||
|
||||
export function inConversation() {
|
||||
return Object.values(convos).some(c => c.active);
|
||||
}
|
||||
|
||||
export function endConversation(sender) {
|
||||
if (convos[sender]) {
|
||||
convos[sender].end();
|
||||
if (self_prompter_paused && !inConversation()) {
|
||||
_resumeSelfPrompter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function endAllChats() {
|
||||
for (const sender in convos) {
|
||||
convos[sender].end();
|
||||
}
|
||||
if (self_prompter_paused) {
|
||||
_resumeSelfPrompter();
|
||||
}
|
||||
}
|
||||
|
||||
export function scheduleSelfPrompter() {
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
|
||||
export function cancelSelfPrompter() {
|
||||
self_prompter_paused = false;
|
||||
}
|
||||
|
||||
class Conversation {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
|
@ -70,91 +28,155 @@ class Conversation {
|
|||
end() {
|
||||
this.active = false;
|
||||
this.ignore_until_start = true;
|
||||
this.inMessageTimer = null;
|
||||
const full_message = _compileInMessages(this);
|
||||
if (full_message.message.trim().length > 0)
|
||||
agent.history.add(this.name, full_message.message);
|
||||
// add the full queued messages to history, but don't respond
|
||||
|
||||
if (agent.last_sender === this.name)
|
||||
agent.last_sender = null;
|
||||
}
|
||||
|
||||
queue(message) {
|
||||
this.in_queue.push(message);
|
||||
}
|
||||
}
|
||||
const convos = {};
|
||||
|
||||
function _getConvo(name) {
|
||||
if (!convos[name])
|
||||
convos[name] = new Conversation(name);
|
||||
return convos[name];
|
||||
}
|
||||
|
||||
export async function startConversation(send_to, message) {
|
||||
const convo = _getConvo(send_to);
|
||||
convo.reset();
|
||||
|
||||
if (agent.self_prompter.on) {
|
||||
await agent.self_prompter.stop();
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
convo.active = true;
|
||||
sendToBot(send_to, message, true);
|
||||
}
|
||||
|
||||
export function sendToBot(send_to, message, start=false) {
|
||||
if (settings.chat_bot_messages)
|
||||
agent.openChat(`(To ${send_to}) ${message}`);
|
||||
if (!isOtherAgent(send_to)) {
|
||||
agent.bot.whisper(send_to, message);
|
||||
return;
|
||||
}
|
||||
const convo = _getConvo(send_to);
|
||||
if (convo.ignore_until_start)
|
||||
return;
|
||||
convo.active = true;
|
||||
|
||||
const end = message.includes('!endConversation');
|
||||
const json = {
|
||||
'message': message,
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
// agent.bot.whisper(send_to, JSON.stringify(json));
|
||||
sendBotChatToServer(send_to, JSON.stringify(json));
|
||||
}
|
||||
|
||||
export async function recieveFromBot(sender, json) {
|
||||
const convo = _getConvo(sender);
|
||||
|
||||
// check if any convo is active besides the sender
|
||||
if (Object.values(convos).some(c => c.active && c.name !== sender)) {
|
||||
sendToBot(sender, 'I am currently busy. Try again later. !endConversation("' + sender + '")');
|
||||
return;
|
||||
class ConversationManager {
|
||||
constructor() {
|
||||
this.convos = {};
|
||||
this.activeConversation = null;
|
||||
}
|
||||
|
||||
console.log(`decoding **${json}**`);
|
||||
const recieved = JSON.parse(json);
|
||||
if (recieved.start) {
|
||||
initAgent(a) {
|
||||
agent = a;
|
||||
}
|
||||
|
||||
_getConvo(name) {
|
||||
if (!this.convos[name])
|
||||
this.convos[name] = new Conversation(name);
|
||||
return this.convos[name];
|
||||
}
|
||||
|
||||
async startConversation(send_to, message) {
|
||||
const convo = this._getConvo(send_to);
|
||||
convo.reset();
|
||||
|
||||
if (agent.self_prompter.on) {
|
||||
await agent.self_prompter.stop();
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
if (convo.active)
|
||||
return;
|
||||
convo.active = true;
|
||||
this.activeConversation = convo;
|
||||
this.sendToBot(send_to, message, true);
|
||||
}
|
||||
if (convo.ignore_until_start)
|
||||
return;
|
||||
|
||||
convo.queue(recieved);
|
||||
sendToBot(send_to, message, start=false) {
|
||||
if (!this.isOtherAgent(send_to)) {
|
||||
agent.bot.whisper(send_to, message);
|
||||
return;
|
||||
}
|
||||
const convo = this._getConvo(send_to);
|
||||
|
||||
if (settings.chat_bot_messages && !start)
|
||||
agent.openChat(`(To ${send_to}) ${message}`);
|
||||
|
||||
if (convo.ignore_until_start)
|
||||
return;
|
||||
convo.active = true;
|
||||
|
||||
const end = message.includes('!endConversation');
|
||||
const json = {
|
||||
'message': message,
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
sendBotChatToServer(send_to, JSON.stringify(json));
|
||||
}
|
||||
|
||||
async recieveFromBot(sender, json) {
|
||||
const convo = this._getConvo(sender);
|
||||
|
||||
// check if any convo is active besides the sender
|
||||
if (Object.values(this.convos).some(c => c.active && c.name !== sender)) {
|
||||
this.sendToBot(sender, `I'm talking to someone else, try again later. !endConversation("${sender}")`);
|
||||
return;
|
||||
}
|
||||
|
||||
// responding to conversation takes priority over self prompting
|
||||
if (agent.self_prompter.on){
|
||||
await agent.self_prompter.stopLoop();
|
||||
const recieved = JSON.parse(json);
|
||||
if (recieved.start) {
|
||||
convo.reset();
|
||||
}
|
||||
if (convo.ignore_until_start)
|
||||
return;
|
||||
|
||||
convo.queue(recieved);
|
||||
|
||||
// responding to conversation takes priority over self prompting
|
||||
if (agent.self_prompter.on){
|
||||
await agent.self_prompter.stopLoop();
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
|
||||
_scheduleProcessInMessage(sender, recieved, convo);
|
||||
}
|
||||
|
||||
responseScheduledFor(sender) {
|
||||
if (!this.isOtherAgent(sender) || !this.inConversation(sender))
|
||||
return false;
|
||||
const convo = this._getConvo(sender);
|
||||
return !!convo.inMessageTimer;
|
||||
}
|
||||
|
||||
isOtherAgent(name) {
|
||||
return agent_names.some((n) => n === name);
|
||||
}
|
||||
|
||||
updateAgents(agents) {
|
||||
agent_names = agents.map(a => a.name);
|
||||
}
|
||||
|
||||
inConversation(other_agent=null) {
|
||||
if (other_agent)
|
||||
return this.convos[other_agent]?.active;
|
||||
return Object.values(this.convos).some(c => c.active);
|
||||
}
|
||||
|
||||
endConversation(sender) {
|
||||
if (this.convos[sender]) {
|
||||
this.convos[sender].end();
|
||||
this.activeConversation = null;
|
||||
if (self_prompter_paused && !this.inConversation()) {
|
||||
_resumeSelfPrompter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endAllConversations() {
|
||||
for (const sender in this.convos) {
|
||||
this.convos[sender].end();
|
||||
}
|
||||
if (self_prompter_paused) {
|
||||
_resumeSelfPrompter();
|
||||
}
|
||||
}
|
||||
|
||||
scheduleSelfPrompter() {
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
|
||||
_scheduleProcessInMessage(sender, recieved, convo);
|
||||
}
|
||||
|
||||
// returns true if the other bot has a scheduled response
|
||||
export function responseScheduledFor(sender) {
|
||||
if (!isOtherAgent(sender))
|
||||
return false;
|
||||
const convo = _getConvo(sender);
|
||||
return !!convo.inMessageTimer;
|
||||
|
||||
cancelSelfPrompter() {
|
||||
self_prompter_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
const convoManager = new ConversationManager();
|
||||
export default convoManager;
|
||||
|
||||
/*
|
||||
This function controls conversation flow by deciding when the bot responds.
|
||||
|
@ -205,7 +227,11 @@ async function _scheduleProcessInMessage(sender, recieved, convo) {
|
|||
}
|
||||
|
||||
function _processInMessageQueue(name) {
|
||||
const convo = _getConvo(name);
|
||||
const convo = convoManager._getConvo(name);
|
||||
_handleFullInMessage(name, _compileInMessages(convo));
|
||||
}
|
||||
|
||||
function _compileInMessages(convo) {
|
||||
let pack = {};
|
||||
let full_message = '';
|
||||
while (convo.in_queue.length > 0) {
|
||||
|
@ -213,19 +239,22 @@ function _processInMessageQueue(name) {
|
|||
full_message += pack.message;
|
||||
}
|
||||
pack.message = full_message;
|
||||
_handleFullInMessage(name, pack);
|
||||
return pack;
|
||||
}
|
||||
|
||||
function _handleFullInMessage(sender, recieved) {
|
||||
console.log(`responding to **${JSON.stringify(recieved)}**`);
|
||||
|
||||
const convo = _getConvo(sender);
|
||||
const convo = convoManager._getConvo(sender);
|
||||
convo.active = true;
|
||||
|
||||
const message = _tagMessage(recieved.message);
|
||||
if (recieved.end)
|
||||
let message = _tagMessage(recieved.message);
|
||||
if (recieved.end) {
|
||||
convo.end();
|
||||
if (recieved.start)
|
||||
sender = 'system'; // bot will respond to system instead of the other bot
|
||||
message = `Conversation with ${sender} ended with message: "${message}"`;
|
||||
}
|
||||
else if (recieved.start)
|
||||
agent.shut_up = false;
|
||||
convo.inMessageTimer = null;
|
||||
agent.handleMessage(sender, message);
|
||||
|
|
|
@ -2,14 +2,11 @@ import * as skills from './library/skills.js';
|
|||
import * as world from './library/world.js';
|
||||
import * as mc from '../utils/mcdata.js';
|
||||
import settings from '../../settings.js'
|
||||
import { handleTranslation } from '../utils/translator.js';
|
||||
|
||||
|
||||
async function say(agent, message) {
|
||||
agent.bot.modes.behavior_log += message + '\n';
|
||||
if (agent.shut_up || !settings.narrate_behavior) return;
|
||||
let translation = await handleTranslation(message);
|
||||
agent.openChat(translation);
|
||||
agent.openChat(message);
|
||||
}
|
||||
|
||||
// a mode is a function that is called every tick to respond immediately to the world
|
||||
|
|
|
@ -72,7 +72,7 @@ export function createMindServer(port = 8080) {
|
|||
console.warn(`Agent ${agentName} tried to send a message but is not logged in`);
|
||||
return;
|
||||
}
|
||||
console.log(`${curAgentName} received message from ${agentName}: ${json}`);
|
||||
console.log(`${curAgentName} sending message to ${agentName}: ${json}`);
|
||||
inGameAgents[agentName].emit('chat-message', curAgentName, json);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue