Merge pull request #3 from kolbytn/fix-placeblock

fixed placeBlock, use Vec3, improved code gen
This commit is contained in:
Max Robinson 2023-11-08 21:19:36 -06:00 committed by GitHub
commit 4acc19f1ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 60 deletions

View file

@ -9,9 +9,18 @@ export class Coder {
} }
queueCode(code) { queueCode(code) {
if (code.startsWith('javascript')) this.current_code = this.santitizeCode(code);
code = code.slice(10); }
this.current_code = code;
santitizeCode(code) {
const remove_strs = ['javascript', 'js']
for (let r of remove_strs) {
if (code.startsWith(r)) {
code = code.slice(r.length);
return code;
}
}
return code;
} }
hasCode() { hasCode() {
@ -35,6 +44,7 @@ export class Coder {
if (!this.current_code) return {success: false, message: "No code to execute."}; if (!this.current_code) return {success: false, message: "No code to execute."};
let src = "import * as skills from '../utils/skills.js';"; let src = "import * as skills from '../utils/skills.js';";
src += "\nimport * as world from '../utils/world.js';" src += "\nimport * as world from '../utils/world.js';"
src += "\nimport Vec3 from 'vec3';"
src += `\n\nexport async function main(bot) {\n`; src += `\n\nexport async function main(bot) {\n`;
for (let line of this.current_code.split('\n')) { for (let line of this.current_code.split('\n')) {
src += ` ${line}\n`; src += ` ${line}\n`;
@ -44,18 +54,18 @@ export class Coder {
console.log("writing to file...", src) console.log("writing to file...", src)
let filename = this.fp + this.file_counter + '.js'; let filename = this.fp + this.file_counter + '.js';
if (this.file_counter > 0) { // if (this.file_counter > 0) {
let prev_filename = this.fp + (this.file_counter-1) + '.js'; // let prev_filename = this.fp + (this.file_counter-1) + '.js';
unlink(prev_filename, (err) => { // unlink(prev_filename, (err) => {
console.log("deleted file " + prev_filename); // console.log("deleted file " + prev_filename);
if (err) console.error(err); // if (err) console.error(err);
}); // });
} // } commented for now, useful to keep files for debugging
this.file_counter++; this.file_counter++;
let result = await this.writeFilePromise(filename, src); let write_result = await this.writeFilePromise(filename, src);
if (result) { if (write_result) {
console.error('Error writing code execution file: ' + result); console.error('Error writing code execution file: ' + result);
return {success: false, message: result}; return {success: false, message: result};
} }
@ -64,10 +74,12 @@ export class Coder {
console.log('executing code...\n'); console.log('executing code...\n');
let execution_file = await import('.'+filename); let execution_file = await import('.'+filename);
this.clear(); this.clear();
let success = await execution_file.main(this.agent.bot); await execution_file.main(this.agent.bot);
return {success, message: ""}; let msg = 'Code executed successfully.';
console.log(msg)
return {success: true, message: msg};
} catch (err) { } catch (err) {
console.error("Problem executing code:" + err); console.error("Code execution triggered catch:" + err);
this.clear(); this.clear();
return {success: false, message: err}; return {success: false, message: err};
} }

View file

@ -22,7 +22,7 @@ export async function sendRequest(turns, systemMessage, stop_seq='***') {
let res = null; let res = null;
try { try {
let completion = await openai.chat.completions.create({ let completion = await openai.chat.completions.create({
model: 'gpt-4', model: 'gpt-3.5-turbo',
messages: messages, messages: messages,
stop: stop_seq, stop: stop_seq,
}); });

View file

@ -4,14 +4,21 @@ import * as world from './world.js';
export function getSkillDocs() { export function getSkillDocs() {
let docstring = "\n*SKILL DOCS\nThese skills are javascript functions that can be called with a js function by writing a code block. Ex: '```// write description comment and code here```' \n\ let docstring = "\n*SKILL DOCS\nThese skills are javascript functions that can be called with a js function by writing a code block. Ex: '```// write description comment and code here```' \n\
Your code block should return a bool indicating if the task was completed successfully. It will return true if you don't write a return statement.\n"; Your code block should return a bool indicating if the task was completed successfully. It will return true if you don't write a return statement.\n";
for (let skillFunc of Object.values(world).concat(Object.values(skills))) { docstring += docHelper(Object.values(skills), 'skills');
docstring += docHelper(Object.values(world), 'world');
return docstring + '*\n';
}
export function docHelper(functions, module_name) {
let docstring = '';
for (let skillFunc of functions) {
let str = skillFunc.toString(); let str = skillFunc.toString();
if (str.includes('/**')){ if (str.includes('/**')){
docstring += skillFunc.name; docstring += module_name+'.'+skillFunc.name;
docstring += str.substring(str.indexOf('/**')+3, str.indexOf('**/')) + '\n'; docstring += str.substring(str.indexOf('/**')+3, str.indexOf('**/')) + '\n';
} }
} }
return docstring + '*\n'; return docstring;
} }
export function containsCodeBlock(message) { export function containsCodeBlock(message) {

View file

@ -1,6 +1,7 @@
import { getItemId } from "./mcdata.js"; import { getItemId } from "./mcdata.js";
import { getCraftingTable, getInventoryCounts, getInventoryStacks, getNearbyMobs, getNearbyBlocks } from "./world.js"; import { getCraftingTable, getInventoryCounts, getInventoryStacks, getNearbyMobs, getNearbyBlocks } from "./world.js";
import pf from 'mineflayer-pathfinder'; import pf from 'mineflayer-pathfinder';
import Vec3 from 'vec3';
export async function craftItem(bot, itemName) { export async function craftItem(bot, itemName) {
@ -71,64 +72,39 @@ export async function breakBlockAt(bot, x, y, z) {
* let position = world.getPosition(bot); * let position = world.getPosition(bot);
* await skills.breakBlockAt(bot, position.x, position.y - 1, position.x); * await skills.breakBlockAt(bot, position.x, position.y - 1, position.x);
**/ **/
let current = bot.blockAt({ x: x, y: y, z: z }); let current = bot.blockAt(Vec3(x, y, z));
if (current.name != 'air') if (current.name != 'air')
await bot.dig(current, true); await bot.dig(current, true);
return true; return true;
} }
export async function placeBlock(bot, blockType, x, y, z) { export async function placeBlock(bot, blockType, x, y, z, faceVec=new Vec3(0, 1, 0)) {
/** /**
* Place the given block type at the given position. * Place the given block type at the given position.
* @param {MinecraftBot} bot, reference to the minecraft bot. * @param {MinecraftBot} bot, reference to the minecraft bot.
* @param {string} blockType, the type of block to place. * @param {string} blockType, the type of block to place.
* @param {number} x, the x coordinate to place the block at. * @param {number} x, the x coordinate of the block to place.
* @param {number} y, the y coordinate to place the block at. * @param {number} y, the y coordinate of the block to place.
* @param {number} z, the z coordinate to place the block at. * @param {number} z, the z coordinate of the block to place.
* @param {Vec3} faceVec, the face of the block to place against. Defaults to the top face.
* @returns {Promise<boolean>} true if the block was placed, false otherwise. * @returns {Promise<boolean>} true if the block was placed, false otherwise.
* @example * @example
* let position = world.getPosition(bot); * let position = world.getPosition(bot);
* await skills.placeBlock(bot, "oak_log", position.x + 1, position.y, position.x); * await skills.placeBlock(bot, "oak_log", position.x + 1, position.y, position.x, new Vec3(1, 0, 0));
**/ **/
let referenceBlock = null; let referenceBlock = bot.blockAt(new Vec3(x, y, z));
let refVec = null; if (referenceBlock.name != 'air')
if (bot.blockAt({ x: x + 1, y: y, z: z }).name != "air") {
referenceBlock = bot.blockAt({ x: x + 1, y: y, z: z });
refVec = { x: x - 1, y: y, z: z };
} else if (bot.blockAt({ x: x - 1, y: y, z: z }).name != "air") {
referenceBlock = bot.blockAt({ x: x - 1, y: y, z: z });
refVec = { x: x + 1, y: y, z: z };
} else if (bot.blockAt({ x: x, y: y + 1, z: z }).name != "air") {
referenceBlock = bot.blockAt({ x: x, y: y + 1, z: z });
refVec = { x: x, y: y - 1, z: z };
} else if (bot.blockAt({ x: x, y: y - 1, z: z }).name != "air") {
referenceBlock = bot.blockAt({ x: x, y: y - 1, z: z });
refVec = { x: x, y: y + 1, z: z };
} else if (bot.blockAt({ x: x, y: y, z: z + 1 }).name != "air") {
referenceBlock = bot.blockAt({ x: x, y: y, z: z + 1 });
refVec = { x: x, y: y, z: z - 1 };
} else if (bot.blockAt({ x: x, y: y, z: z - 1 }).name != "air") {
referenceBlock = bot.blockAt({ x: x, y: y, z: z - 1 });
refVec = { x: x, y: y, z: z + 1 };
} else {
return false; return false;
} let block = bot.inventory.items().find(item => item.name === blockType);
if (!block)
let block = null;
for (let stack of getInventoryStacks(bot)) {
if (stack.name == blockType) {
block = stack;
break;
}
}
if (block == null)
return false; return false;
breakBlockAt(bot, x, y, z);
await bot.equip(block, 'hand'); await bot.equip(block, 'hand');
await bot.placeBlock(referenceBlock, refVec); bot.placeBlock(referenceBlock, faceVec).then(() => {
return true; return true;
}).catch((err) => {
return false;
});
} }