2023-11-06 21:53:15 -08:00
import { writeFileSync } from 'fs' ;
2023-08-15 23:39:02 -07:00
2023-08-17 00:00:57 -07:00
import { getDetailedSkills , getWorldFunctions } from './utils/context.js' ;
2023-08-15 23:39:02 -07:00
import { sendRequest } from './utils/gpt.js' ;
function buildSystemMessage ( bot ) {
2023-08-17 00:00:57 -07:00
let message = 'You are a helpful Minecraft bot. Given the dialogue, reflect on what you are doing and generate javascript code to accomplish that goal. Use only functions listed below to write your code.' ;
message += "\n\n" + getDetailedSkills ( ) ;
message += "\n\n" + getWorldFunctions ( ) ;
2023-08-15 23:39:02 -07:00
return message ;
}
function buildExamples ( ) {
2023-09-29 15:53:16 -07:00
return [
2023-08-15 23:39:02 -07:00
` mr_steve2: Will you help me collect wood?
2023-08-17 00:00:57 -07:00
! blocks
2023-08-15 23:39:02 -07:00
\ ` \` \`
2023-08-17 00:00:57 -07:00
NEARBY _BLOCKS
- oak _log
- dirt
- cobblestone
2023-08-15 23:39:02 -07:00
\ ` \` \`
2023-08-17 00:00:57 -07:00
Me : I ' d be glad to help you collect wood . ` ,
2023-09-29 15:53:16 -07:00
` I'm going to help mr_steve2 collect wood. The type of wood block nearby is 'oak_log'. I'll adjust my code to collect an 'oak_log' for mr_steve2.
2023-08-17 00:00:57 -07:00
\ ` \` \`
2023-09-29 15:53:16 -07:00
await skills . collectBlock ( bot , 'oak_log' ) ;
await skills . giveToPlayer ( bot , 'oak_log' , 'mr_steve2' ) ;
2023-08-15 23:39:02 -07:00
\ ` \` \` ` ,
` sally32: What are you doing?
2023-08-17 00:00:57 -07:00
! action
2023-08-15 23:39:02 -07:00
\ ` \` \`
2023-09-29 15:53:16 -07:00
await skills . equipItem ( bot , 'wooden_pickaxe' ) ;
while ( world . getInventory ( bot ) . coal _ore < 10 ) {
await skills . collectBlock ( bot , 'coal_ore' ) ;
}
2023-08-17 00:00:57 -07:00
\ ` \` \`
Me : I ' m looking for coal . Have you seen any ?
sally32 : Yes , there ' s some in this cave , follow me . ` ,
` I'm going to follow sally32 to the cave and collect coal. I'll adjust my code to follow sally32 until I find coal_ore and then I'll mine it.
\ ` \` \`
while ( true ) {
2023-09-29 15:53:16 -07:00
await skills . goToPlayer ( bot , 'sally32' ) ;
2023-08-17 00:00:57 -07:00
if ( world . getNearbyBlocks ( bot ) . includes ( 'coal_ore' ) ) {
break ;
}
}
2023-09-29 15:53:16 -07:00
await skills . equipItem ( bot , 'wooden_pickaxe' ) ;
while ( world . getInventory ( bot ) . coal _ore < 10 ) {
await skills . collectBlock ( bot , 'coal_ore' ) ;
}
2023-08-15 23:39:02 -07:00
\ ` \` \` ` ,
2023-08-17 00:00:57 -07:00
` user42: come here
Me : Sure ! I ' m on my way . ` ,
` I'm going to navigate to user42.
2023-08-15 23:39:02 -07:00
\ ` \` \`
2023-09-29 15:53:16 -07:00
await skills . goToPlayer ( bot , 'user42' ) ;
2023-08-15 23:39:02 -07:00
\ ` \` \` ` ,
2023-11-05 15:38:52 -06:00
` user42: execute some code that says "hello world"
Me : Okay , I ' ll do that now . ` ,
` I'm going to log "hello world" to the console.
\ ` \` \`
console . log ( 'hello world' ) ;
\ ` \` \` ` ,
]
2023-08-15 23:39:02 -07:00
}
2023-08-17 00:00:57 -07:00
export var currentCode = '' ;
export async function executeCode ( bot ) {
let src = "import * as skills from './utils/skills.js';" ;
src += "\nimport * as world from './utils/world.js';"
src += ` \n \n export async function main(bot) { \n ` ;
for ( let line of currentCode . split ( '\n' ) ) {
2023-08-15 23:39:02 -07:00
src += ` ${ line } \n ` ;
}
src += ` } \n ` ;
2023-11-06 21:53:15 -08:00
writeFileSync ( './temp.js' , src , ( err ) => {
2023-08-15 23:39:02 -07:00
if ( err ) throw err ;
} ) ;
2023-08-17 00:00:57 -07:00
console . log ( 'executing code...\n' + currentCode ) ;
try {
2023-11-05 15:38:52 -06:00
let ouput = await ( await import ( './temp.js' ) ) . main ( bot ) ;
console . log ( ` Code output: * \n ${ ouput } \n * ` ) ;
2023-08-17 00:00:57 -07:00
} catch ( err ) {
console . log ( err ) ;
2023-09-29 12:53:56 -07:00
currentCode = '' ;
2023-08-17 00:00:57 -07:00
return false ;
}
2023-09-29 12:53:56 -07:00
currentCode = '' ;
2023-08-17 00:00:57 -07:00
return true ;
2023-08-15 23:39:02 -07:00
}
2023-08-17 00:00:57 -07:00
export async function writeCode ( bot , username , messages ) {
2023-08-15 23:39:02 -07:00
let turns = buildExamples ( ) ;
2023-08-17 00:00:57 -07:00
// For now, get rid of the first 6 example messages
2023-11-05 15:38:52 -06:00
messages = messages . slice ( 8 ) ; // TODO: fix this, very spaghetti
2023-08-17 00:00:57 -07:00
let startIndex = messages . length - 6 ;
if ( startIndex < 0 )
startIndex = 0 ;
2023-11-05 15:38:52 -06:00
let nextTurn = '' ;
2023-08-17 00:00:57 -07:00
for ( let i = startIndex ; i < messages . length ; i ++ ) {
if ( i % 2 == 0 ) {
2023-11-05 15:38:52 -06:00
nextTurn += ` ${ username } : ${ messages [ i ] } \n \n ` ;
2023-08-17 00:00:57 -07:00
} else {
2023-11-05 15:38:52 -06:00
nextTurn += ` Me: ${ messages [ i ] } \n \n ` ;
turns . push ( nextTurn ) ;
nextTurn = '' ;
2023-08-17 00:00:57 -07:00
}
}
2023-11-05 15:38:52 -06:00
if ( nextTurn )
turns . push ( nextTurn ) ;
2023-08-17 00:00:57 -07:00
turns [ turns . length - 1 ] = turns [ turns . length - 1 ] . trim ( ) ;
2023-11-05 15:38:52 -06:00
console . log ( "Action request input:" , turns ) ;
2023-08-15 23:39:02 -07:00
let systemMessage = buildSystemMessage ( bot ) ;
let actResponse = await sendRequest ( turns , systemMessage ) ;
2023-11-05 15:38:52 -06:00
console . log ( "Action response:" , actResponse ) ;
2023-08-15 23:39:02 -07:00
let code = actResponse . split ( '\`\`\`' ) ;
2023-11-05 15:38:52 -06:00
console . log ( code ) ;
2023-08-15 23:39:02 -07:00
if ( code . length <= 1 )
2023-09-29 12:53:56 -07:00
return code ;
2023-08-15 23:39:02 -07:00
if ( ! code [ 1 ] . trim ( ) )
2023-09-29 12:53:56 -07:00
return code ;
2023-08-15 23:39:02 -07:00
currentCode = code [ 1 ] . trim ( ) ;
if ( currentCode . slice ( 0 , 10 ) == 'javascript' )
currentCode = currentCode . slice ( 10 ) . trim ( ) ;
2023-09-29 12:53:56 -07:00
return currentCode ;
2023-08-15 23:39:02 -07:00
}