mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-03 13:55:36 +02:00
added various fixes/improvements
This commit is contained in:
parent
feac9ab424
commit
3e3e80c0ed
9 changed files with 55 additions and 30 deletions
|
@ -3,5 +3,5 @@
|
|||
"host": "localhost",
|
||||
"port": 55916,
|
||||
"auth": "offline",
|
||||
"allow_insecure_coding": true
|
||||
"allow_insecure_coding": false
|
||||
}
|
|
@ -29,7 +29,7 @@ export class Coder {
|
|||
|
||||
// write custom code to file and import it
|
||||
async stageCode(code) {
|
||||
code = this.santitizeCode(code);
|
||||
code = this.sanitizeCode(code);
|
||||
let src = '';
|
||||
code = code.replaceAll('console.log(', 'log(bot,');
|
||||
code = code.replaceAll('log("', 'log(bot,"');
|
||||
|
@ -62,7 +62,8 @@ export class Coder {
|
|||
return await import('../..' + this.fp + filename);
|
||||
}
|
||||
|
||||
santitizeCode(code) {
|
||||
sanitizeCode(code) {
|
||||
code = code.trim();
|
||||
const remove_strs = ['Javascript', 'javascript', 'js']
|
||||
for (let r of remove_strs) {
|
||||
if (code.startsWith(r)) {
|
||||
|
@ -93,6 +94,7 @@ export class Coder {
|
|||
let res = await this.generateCodeLoop(agent_history);
|
||||
this.generating = false;
|
||||
if (!res.interrupted) this.agent.bot.emit('idle');
|
||||
return res.message;
|
||||
}
|
||||
|
||||
async generateCodeLoop(agent_history) {
|
||||
|
@ -107,7 +109,7 @@ export class Coder {
|
|||
let failures = 0;
|
||||
for (let i=0; i<5; i++) {
|
||||
if (this.agent.bot.interrupt_code)
|
||||
return;
|
||||
return {success: true, message: null, interrupted: true, timedout: false};
|
||||
console.log(messages)
|
||||
let res = await sendRequest(messages, system_message);
|
||||
console.log('Code generation response:', res)
|
||||
|
@ -120,8 +122,7 @@ export class Coder {
|
|||
return {success: true, message: null, interrupted: false, timedout: false};
|
||||
}
|
||||
if (failures >= 1) {
|
||||
agent_history.add('system', 'Action failed, agent would not write code.');
|
||||
return {success: false, message: null, interrupted: false, timedout: false};
|
||||
return {success: false, message: 'Action failed, agent would not write code.', interrupted: false, timedout: false};
|
||||
}
|
||||
messages.push({
|
||||
role: 'system',
|
||||
|
@ -143,7 +144,7 @@ export class Coder {
|
|||
|
||||
if (code_return.interrupted && !code_return.timedout)
|
||||
return {success: false, message: null, interrupted: true, timedout: false};
|
||||
console.log(code_return.message);
|
||||
console.log("Code generation result:", code_return.success, code_return.message);
|
||||
|
||||
messages.push({
|
||||
role: 'assistant',
|
||||
|
@ -219,7 +220,7 @@ export class Coder {
|
|||
formatOutput(bot) {
|
||||
if (bot.interrupt_code && !this.timedout) return '';
|
||||
let output = bot.output;
|
||||
const MAX_OUT = 1000;
|
||||
const MAX_OUT = 500;
|
||||
if (output.length > MAX_OUT) {
|
||||
output = `Code output is very long (${output.length} chars) and has been shortened.\n
|
||||
First outputs:\n${output.substring(0, MAX_OUT/2)}\n...skipping many lines.\nFinal outputs:\n ${output.substring(output.length - MAX_OUT/2)}`;
|
||||
|
|
|
@ -26,7 +26,7 @@ export const actionsList = [
|
|||
perform: async function (agent) {
|
||||
if (!settings.allow_insecure_coding)
|
||||
return 'Agent is not allowed to write code.';
|
||||
await agent.coder.generateCode(agent.history);
|
||||
return await agent.coder.generateCode(agent.history);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ export const actionsList = [
|
|||
}
|
||||
},
|
||||
{
|
||||
name: '!clear',
|
||||
name: '!clearChat',
|
||||
description: 'Clear the chat history.',
|
||||
perform: async function (agent) {
|
||||
agent.history.clear();
|
||||
|
@ -84,7 +84,7 @@ export const actionsList = [
|
|||
},
|
||||
{
|
||||
name: '!followPlayer',
|
||||
description: 'Endlessly follow the given player. Will defend that player if self_defense mode is on. Ex: !followPlayer("stevie")',
|
||||
description: 'Endlessly follow the given player. Will defend that player if self_defense mode is on. Ex: !followPlayer("stevie", 4)',
|
||||
params: {
|
||||
'player_name': '(string) The name of the player to follow.',
|
||||
'follow_dist': '(number) The distance to follow from.'
|
||||
|
|
|
@ -59,7 +59,7 @@ export const queryList = [
|
|||
}
|
||||
},
|
||||
{
|
||||
name: "!blocks",
|
||||
name: "!nearbyBlocks",
|
||||
description: "Get the blocks near the bot.",
|
||||
perform: function (agent) {
|
||||
let bot = agent.bot;
|
||||
|
|
|
@ -29,8 +29,8 @@ export class History {
|
|||
}
|
||||
|
||||
getSystemMessage() {
|
||||
let system_message = `You are a playful Minecraft bot named '${this.name}' that can communicate with players, see, move, mine, build, and interact with the world by using commands. Act human-like as if you were a typical Minecraft player, rather than an AI. Be very brief in your responses, use commands often, and do not give instructions unless asked.
|
||||
Don't pretend to act, use commands immediately when requested. Do NOT do this: "Sure, I'll follow you! *follows you*", instead do this: "Sure I'll follow you! !followPlayer('steve')". Have fun :) \n`;
|
||||
let system_message = `You are a playful Minecraft bot named '${this.name}' that can communicate with players, see, move, mine, build, and interact with the world by using commands. 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, do not give instructions unless asked, and do not 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('bingo', 3)". Have fun :) \n`;
|
||||
system_message += getCommandDocs();
|
||||
if (this.bio != '')
|
||||
system_message += '\n\nBio:\n' + this.bio;
|
||||
|
|
|
@ -421,14 +421,9 @@ export async function breakBlockAt(bot, x, y, z) {
|
|||
* let position = world.getPosition(bot);
|
||||
* await skills.breakBlockAt(bot, position.x, position.y - 1, position.x);
|
||||
**/
|
||||
if (x == null || y == null || z == null) throw new Error('Invalid position to break block at.');
|
||||
let block = bot.blockAt(Vec3(x, y, z));
|
||||
if (block.name !== 'air' && block.name !== 'water' && block.name !== 'lava') {
|
||||
await bot.tool.equipForBlock(block);
|
||||
const itemId = bot.heldItem ? bot.heldItem.type : null
|
||||
if (!block.canHarvest(itemId)) {
|
||||
log(bot, `Don't have right tools to break ${block.name}.`);
|
||||
return false;
|
||||
}
|
||||
if (bot.entity.position.distanceTo(block.position) > 4.5) {
|
||||
let pos = block.position;
|
||||
let movements = new pf.Movements(bot);
|
||||
|
@ -437,7 +432,18 @@ export async function breakBlockAt(bot, x, y, z) {
|
|||
bot.pathfinder.setMovements(movements);
|
||||
await bot.pathfinder.goto(new pf.goals.GoalNear(pos.x, pos.y, pos.z, 4));
|
||||
}
|
||||
await bot.tool.equipForBlock(block);
|
||||
const itemId = bot.heldItem ? bot.heldItem.type : null
|
||||
if (!block.canHarvest(itemId)) {
|
||||
log(bot, `Don't have right tools to break ${block.name}.`);
|
||||
return false;
|
||||
}
|
||||
await bot.dig(block, true);
|
||||
log(bot, `Broke ${block.name} at x:${x.toFixed(1)}, y:${y.toFixed(1)}, z:${z.toFixed(1)}.`);
|
||||
}
|
||||
else {
|
||||
log(bot, `Skipping block at x:${x.toFixed(1)}, y:${y.toFixed(1)}, z:${z.toFixed(1)} because it is ${block.name}.`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
[
|
||||
{"role": "user", "content": "grombo_Xx: What do you see?"},
|
||||
{"role": "assistant", "content": "Let me see... !blocks"},
|
||||
{"role": "assistant", "content": "Let me see... !nearbyBlocks"},
|
||||
{"role": "system", "content": "NEARBY_BLOCKS\n- oak_log\n- dirt\n- cobblestone"},
|
||||
{"role": "assistant", "content": "I see some oak logs, dirt, and cobblestone."}
|
||||
],
|
||||
|
||||
[
|
||||
{"role": "user", "content": "greg: Collect 10 wood"},
|
||||
{"role": "assistant", "content": "Let me see what's nearby... !blocks"},
|
||||
{"role": "assistant", "content": "Let me see what's nearby... !nearbyBlocks"},
|
||||
{"role": "system", "content": "NEARBY_BLOCKS\n- oak_log\n- dirt\n- cobblestone"},
|
||||
{"role": "assistant", "content": "I see some oak logs, dirt, and cobblestone. I'll collect oak logs. !collectBlocks('oak_log', 10)"}
|
||||
],
|
||||
|
@ -77,8 +77,13 @@
|
|||
],
|
||||
|
||||
[
|
||||
{"role": "user", "content": "brung00: build a house"},
|
||||
{"role": "assistant", "content": "Sure, I'll try to build a house where I am. !newAction"}
|
||||
{"role": "user", "content": "poppy: build a cobblestone house"},
|
||||
{"role": "assistant", "content": "Sure, I'll to build a small cobblestone house where I am. !newAction"}
|
||||
],
|
||||
|
||||
[
|
||||
{"role": "user", "content": "zib: build a dirt tower"},
|
||||
{"role": "assistant", "content": "Sure, I'll build a dirt tower 5 tall where I am. !newAction"}
|
||||
],
|
||||
|
||||
[
|
||||
|
|
|
@ -4,7 +4,7 @@ import { stringifyTurns } from './text.js';
|
|||
|
||||
|
||||
export class Examples {
|
||||
constructor(select_num=3) {
|
||||
constructor(select_num=2) {
|
||||
this.examples = [];
|
||||
this.select_num = select_num;
|
||||
}
|
||||
|
|
|
@ -20,14 +20,28 @@ else {
|
|||
|
||||
const openai = new OpenAIApi(openAiConfig);
|
||||
|
||||
let counter = 0;
|
||||
let request_queue = [];
|
||||
export async function sendRequest(turns, systemMessage) {
|
||||
// this wrapper function ensures that new requests await the completion of previous requests in order
|
||||
let id = counter++;
|
||||
request_queue.push(id);
|
||||
if (request_queue.length > 1)
|
||||
console.log('awaiting previous requests to complete, queueing request', id);
|
||||
while (request_queue[0] !== id) {
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
let res = await queryGPT(turns, systemMessage);
|
||||
request_queue.shift();
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function sendRequest(turns, systemMessage, stop_seq='***') {
|
||||
|
||||
async function queryGPT(turns, systemMessage, stop_seq='***') {
|
||||
let messages = [{'role': 'system', 'content': systemMessage}].concat(turns);
|
||||
|
||||
let res = null;
|
||||
try {
|
||||
console.log('Awaiting openai api response...')
|
||||
console.log('Awaiting openai api response...');
|
||||
let completion = await openai.chat.completions.create({
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages: messages,
|
||||
|
@ -35,13 +49,12 @@ export async function sendRequest(turns, systemMessage, stop_seq='***') {
|
|||
});
|
||||
if (completion.choices[0].finish_reason == 'length')
|
||||
throw new Error('Context length exceeded');
|
||||
console.log('Received.')
|
||||
res = completion.choices[0].message.content;
|
||||
}
|
||||
catch (err) {
|
||||
if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) {
|
||||
console.log('Context length exceeded, trying again with shorter context.');
|
||||
return await sendRequest(turns.slice(1), systemMessage, stop_seq);
|
||||
return await queryGPT(turns.slice(1), systemMessage, stop_seq);
|
||||
} else {
|
||||
console.log(err);
|
||||
res = 'My brain disconnected, try again.';
|
||||
|
|
Loading…
Add table
Reference in a new issue