2023-08-15 23:39:02 -07:00
import { writeFile } from 'fs' ;
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 ( ) {
return [
` 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 . ` ,
` 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 10 'oak_log' for mr_steve2.
\ ` \` \`
await skills . CollectBlock ( bot , 'oak_log' , 10 ) ;
await skills . GoToPlayer ( bot , 'mr_steve2' ) ;
await skills . DropItem ( bot , 'oak_log' , 10 ) ;
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
\ ` \` \`
await skills . ExploreToFind ( bot , 'coal_ore' ) ;
await skills . EquipItem ( bot , 'wooden_pickaxe' ) ;
await skills . CollectBlock ( bot , 'coal_ore' , 10 ) ;
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 ) {
await skills . GoToPlayer ( bot , 'sally32' ) ;
if ( world . getNearbyBlocks ( bot ) . includes ( 'coal_ore' ) ) {
break ;
}
}
await skills . EquipItem ( bot , 'wooden_pickaxe' ) ;
await skills . CollectBlock ( bot , 'coal_ore' , 10 ) ;
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-08-17 00:00:57 -07:00
await skills . GoToPlayer ( bot , 'user42' ) ;
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 ` ;
writeFile ( './temp.js' , src , ( err ) => {
if ( err ) throw err ;
} ) ;
2023-08-17 00:00:57 -07:00
console . log ( 'executing code...\n' + currentCode ) ;
try {
await ( await import ( './temp.js' ) ) . main ( bot ) ;
} catch ( err ) {
console . log ( err ) ;
return false ;
}
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
messages = messages . slice ( 6 ) ;
let startIndex = messages . length - 6 ;
if ( startIndex < 0 )
startIndex = 0 ;
turns . push ( '' ) ;
for ( let i = startIndex ; i < messages . length ; i ++ ) {
if ( i % 2 == 0 ) {
turns [ turns . length - 1 ] += ` \n \n ${ username } : ${ messages [ i ] } ` ;
} else {
turns [ turns . length - 1 ] += ` \n \n Me: ${ messages [ i ] } ` ;
}
}
turns [ turns . length - 1 ] = turns [ turns . length - 1 ] . trim ( ) ;
2023-08-15 23:39:02 -07:00
let systemMessage = buildSystemMessage ( bot ) ;
let actResponse = await sendRequest ( turns , systemMessage ) ;
console . log ( actResponse ) ;
let code = actResponse . split ( '\`\`\`' ) ;
if ( code . length <= 1 )
return false ;
if ( ! code [ 1 ] . trim ( ) )
return false ;
currentCode = code [ 1 ] . trim ( ) ;
if ( currentCode . slice ( 0 , 10 ) == 'javascript' )
currentCode = currentCode . slice ( 10 ) . trim ( ) ;
return true ;
}