mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-09-01 20:03:09 +02:00
improved interrupt response logic, removed collectallblocks
This commit is contained in:
parent
1fe1bda789
commit
a853995571
5 changed files with 44 additions and 28 deletions
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "gort: (FROM OTHER BOT)Let's do it, onward!"},
|
{"role": "user", "content": "gort: (FROM OTHER BOT)Let's do it, onward!"},
|
||||||
{"role": "assistant", "content": "Alright, let's see what's nearby... !nearbyBlocks"}
|
{"role": "assistant", "content": "Alright, I'll start by getting some cobblestone. !collectBlocks('stone', 10)"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { ActionManager } from './action_manager.js';
|
||||||
import { NPCContoller } from './npc/controller.js';
|
import { NPCContoller } from './npc/controller.js';
|
||||||
import { MemoryBank } from './memory_bank.js';
|
import { MemoryBank } from './memory_bank.js';
|
||||||
import { SelfPrompter } from './self_prompter.js';
|
import { SelfPrompter } from './self_prompter.js';
|
||||||
import { isOtherAgent, initConversationManager, sendToBot, endAllChats } from './conversation.js';
|
import { isOtherAgent, initConversationManager, sendToBot, endAllChats, responseScheduledFor} from './conversation.js';
|
||||||
import { handleTranslation, handleEnglishTranslation } from '../utils/translator.js';
|
import { handleTranslation, handleEnglishTranslation } from '../utils/translator.js';
|
||||||
import { addViewer } from './viewer.js';
|
import { addViewer } from './viewer.js';
|
||||||
import settings from '../../settings.js';
|
import settings from '../../settings.js';
|
||||||
|
@ -191,7 +191,7 @@ export class Agent {
|
||||||
}
|
}
|
||||||
else if (save_data?.last_sender) {
|
else if (save_data?.last_sender) {
|
||||||
this.last_sender = save_data.last_sender;
|
this.last_sender = save_data.last_sender;
|
||||||
await this.handleMessage(this.last_sender, `(You have restarted and this message is auto-generated. Continue the conversation with ${this.last_sender})`);
|
await this.handleMessage('system', `You have restarted and this message is auto-generated. Continue the conversation with ${this.last_sender}`);
|
||||||
}
|
}
|
||||||
else if (init_message) {
|
else if (init_message) {
|
||||||
await this.handleMessage('system', init_message, 2);
|
await this.handleMessage('system', init_message, 2);
|
||||||
|
@ -265,14 +265,12 @@ export class Agent {
|
||||||
|
|
||||||
if (!self_prompt)
|
if (!self_prompt)
|
||||||
this.last_sender = source;
|
this.last_sender = source;
|
||||||
else
|
|
||||||
this.last_sender = null;
|
|
||||||
|
|
||||||
// Now translate the message
|
// Now translate the message
|
||||||
message = await handleEnglishTranslation(message);
|
message = await handleEnglishTranslation(message);
|
||||||
console.log('received message from', source, ':', message);
|
console.log('received message from', source, ':', message);
|
||||||
|
|
||||||
const checkInterrupt = () => this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up;
|
const checkInterrupt = () => this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up || responseScheduledFor(source);
|
||||||
|
|
||||||
let behavior_log = this.bot.modes.flushBehaviorLog();
|
let behavior_log = this.bot.modes.flushBehaviorLog();
|
||||||
if (behavior_log.trim().length > 0) {
|
if (behavior_log.trim().length > 0) {
|
||||||
|
@ -347,6 +345,13 @@ export class Agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
async routeResponse(to_player, message, translate_up_to=-1) {
|
async routeResponse(to_player, message, translate_up_to=-1) {
|
||||||
|
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
|
||||||
|
// so it can respond to events like death but be routed back to the last sender
|
||||||
|
to_player = this.last_sender;
|
||||||
|
}
|
||||||
|
|
||||||
if (isOtherAgent(to_player)) {
|
if (isOtherAgent(to_player)) {
|
||||||
sendToBot(to_player, message);
|
sendToBot(to_player, message);
|
||||||
return;
|
return;
|
||||||
|
@ -362,7 +367,7 @@ export class Agent {
|
||||||
// newlines are interpreted as separate chats, which triggers spam filters. replace them with spaces
|
// newlines are interpreted as separate chats, which triggers spam filters. replace them with spaces
|
||||||
message = message.replaceAll('\n', ' ');
|
message = message.replaceAll('\n', ' ');
|
||||||
|
|
||||||
if (to_player === 'system' || to_player === this.name)
|
if (self_prompt)
|
||||||
this.bot.chat(message);
|
this.bot.chat(message);
|
||||||
else
|
else
|
||||||
this.bot.whisper(to_player, message);
|
this.bot.whisper(to_player, message);
|
||||||
|
|
|
@ -225,18 +225,6 @@ export const actionsList = [
|
||||||
await skills.collectBlock(agent.bot, type, num);
|
await skills.collectBlock(agent.bot, type, num);
|
||||||
}, false, 10) // 10 minute timeout
|
}, false, 10) // 10 minute timeout
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: '!collectAllBlocks',
|
|
||||||
description: 'Collect all the nearest blocks of a given type until told to stop.',
|
|
||||||
params: {
|
|
||||||
'type': { type: 'BlockName', description: 'The block type to collect.' }
|
|
||||||
},
|
|
||||||
perform: runAsAction(async (agent, type) => {
|
|
||||||
let success = await skills.collectBlock(agent.bot, type, 1);
|
|
||||||
if (!success)
|
|
||||||
agent.actions.cancelResume();
|
|
||||||
}, true, 3) // 3 minute timeout
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: '!craftRecipe',
|
name: '!craftRecipe',
|
||||||
description: 'Craft the given recipe a given number of times.',
|
description: 'Craft the given recipe a given number of times.',
|
||||||
|
|
|
@ -106,7 +106,8 @@ export function sendToBot(send_to, message, start=false) {
|
||||||
const convo = _getConvo(send_to);
|
const convo = _getConvo(send_to);
|
||||||
if (convo.ignore_until_start)
|
if (convo.ignore_until_start)
|
||||||
return;
|
return;
|
||||||
|
convo.active = true;
|
||||||
|
|
||||||
const end = message.includes('!endConversation');
|
const end = message.includes('!endConversation');
|
||||||
const json = {
|
const json = {
|
||||||
'message': message,
|
'message': message,
|
||||||
|
@ -139,6 +140,14 @@ export async function recieveFromBot(sender, json) {
|
||||||
_scheduleProcessInMessage(sender, recieved, convo);
|
_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This function controls conversation flow by deciding when the bot responds.
|
This function controls conversation flow by deciding when the bot responds.
|
||||||
|
@ -149,7 +158,7 @@ The logic is as follows:
|
||||||
- If both bots are busy, don't respond until someone is done, excluding a few actions that allow fast responses
|
- If both bots are busy, don't respond until someone is done, excluding a few actions that allow fast responses
|
||||||
- New messages recieved during the delay will reset the delay following this logic, and be queued to respond in bulk
|
- New messages recieved during the delay will reset the delay following this logic, and be queued to respond in bulk
|
||||||
*/
|
*/
|
||||||
const talkOverActions = ['stay', 'followPlayer'];
|
const talkOverActions = ['stay', 'followPlayer', 'mode:']; // all mode actions
|
||||||
const fastDelay = 200;
|
const fastDelay = 200;
|
||||||
const longDelay = 5000;
|
const longDelay = 5000;
|
||||||
async function _scheduleProcessInMessage(sender, recieved, convo) {
|
async function _scheduleProcessInMessage(sender, recieved, convo) {
|
||||||
|
@ -171,10 +180,16 @@ async function _scheduleProcessInMessage(sender, recieved, convo) {
|
||||||
scheduleResponse(longDelay);
|
scheduleResponse(longDelay);
|
||||||
else if (!agent.isIdle()) {
|
else if (!agent.isIdle()) {
|
||||||
// I'm busy but other bot isn't
|
// I'm busy but other bot isn't
|
||||||
let shouldRespond = await agent.prompter.promptShouldRespondToBot(recieved.message);
|
let canTalkOver = talkOverActions.some(a => agent.actions.currentActionLabel.includes(a));
|
||||||
console.log(`${agent.name} decided to ${shouldRespond?'respond':'not respond'} to ${sender}`);
|
if (canTalkOver) {
|
||||||
if (shouldRespond)
|
|
||||||
scheduleResponse(fastDelay);
|
scheduleResponse(fastDelay);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let shouldRespond = await agent.prompter.promptShouldRespondToBot(recieved.message);
|
||||||
|
console.log(`${agent.name} decided to ${shouldRespond?'respond':'not respond'} to ${sender}`);
|
||||||
|
if (shouldRespond)
|
||||||
|
scheduleResponse(fastDelay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// neither are busy
|
// neither are busy
|
||||||
|
@ -182,8 +197,7 @@ async function _scheduleProcessInMessage(sender, recieved, convo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _processInMessageQueue(name) {
|
||||||
export function _processInMessageQueue(name) {
|
|
||||||
const convo = _getConvo(name);
|
const convo = _getConvo(name);
|
||||||
let pack = null;
|
let pack = null;
|
||||||
let full_message = '';
|
let full_message = '';
|
||||||
|
@ -195,10 +209,11 @@ export function _processInMessageQueue(name) {
|
||||||
_handleFullInMessage(name, pack);
|
_handleFullInMessage(name, pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _handleFullInMessage(sender, recieved) {
|
function _handleFullInMessage(sender, recieved) {
|
||||||
console.log(`responding to **${JSON.stringify(recieved)}**`);
|
console.log(`responding to **${JSON.stringify(recieved)}**`);
|
||||||
|
|
||||||
const convo = _getConvo(sender);
|
const convo = _getConvo(sender);
|
||||||
|
convo.active = true;
|
||||||
|
|
||||||
const message = _tagMessage(recieved.message);
|
const message = _tagMessage(recieved.message);
|
||||||
if (recieved.end) {
|
if (recieved.end) {
|
||||||
|
@ -209,6 +224,7 @@ export function _handleFullInMessage(sender, recieved) {
|
||||||
}
|
}
|
||||||
if (recieved.start)
|
if (recieved.start)
|
||||||
agent.shut_up = false;
|
agent.shut_up = false;
|
||||||
|
convo.inMessageTimer = null;
|
||||||
agent.handleMessage(sender, message);
|
agent.handleMessage(sender, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,14 @@ async function execute(mode, agent, func, timeout=-1) {
|
||||||
}, { timeout });
|
}, { timeout });
|
||||||
mode.active = false;
|
mode.active = false;
|
||||||
console.log(`Mode ${mode.name} finished executing, code_return: ${code_return.message}`);
|
console.log(`Mode ${mode.name} finished executing, code_return: ${code_return.message}`);
|
||||||
if (interrupted_action && !agent.actions.resume_func && !agent.self_prompter.on) {
|
|
||||||
|
let should_reprompt =
|
||||||
|
interrupted_action && // it interrupted a previous action
|
||||||
|
!agent.actions.resume_func && // there is no resume function
|
||||||
|
!agent.self_prompter.on && // self prompting is not on
|
||||||
|
!code_return.interrupted; // this mode action was not interrupted by something else
|
||||||
|
|
||||||
|
if (should_reprompt) {
|
||||||
// auto prompt to respond to the interruption
|
// auto prompt to respond to the interruption
|
||||||
let role = agent.last_sender ? agent.last_sender : 'system';
|
let role = agent.last_sender ? agent.last_sender : 'system';
|
||||||
let logs = agent.bot.modes.flushBehaviorLog();
|
let logs = agent.bot.modes.flushBehaviorLog();
|
||||||
|
|
Loading…
Add table
Reference in a new issue