2023-11-07 12:00:55 -06:00
import { initBot } from './utils/mcdata.js' ;
2023-11-07 09:44:56 -06:00
import { sendRequest } from './utils/gpt.js' ;
import { History } from './utils/history.js' ;
2023-11-07 12:00:55 -06:00
import { Coder } from './utils/coder.js' ;
2023-11-13 20:33:34 -08:00
import { getQuery , containsQuery } from './utils/queries.js' ;
import { containsCodeBlock } from './utils/skill_library.js' ;
2023-11-07 09:44:56 -06:00
export class Agent {
2023-11-19 15:34:53 -06:00
constructor ( name , save _path , restart _memory = false ) {
2023-11-07 09:44:56 -06:00
this . name = name ;
2023-11-07 12:00:55 -06:00
this . bot = initBot ( name ) ;
2023-11-15 13:18:38 -08:00
this . history = new History ( this , save _path ) ;
2023-11-07 12:00:55 -06:00
this . coder = new Coder ( this ) ;
2023-11-19 15:34:53 -06:00
if ( ! restart _memory ) {
this . history . load ( ) ;
}
2023-12-04 23:26:21 -08:00
// Add the default behaviors and events
else {
this . history . default = ` let blocks = world.getNearbyBlockTypes(bot, 4);
let block _type = blocks [ Math . floor ( Math . random ( ) * blocks . length ) ] ;
await skills . collectBlock ( bot , block _type ) ;
await new Promise ( r => setTimeout ( r , 1000 ) ) ;
let players = world . getNearbyPlayerNames ( bot ) ;
let player _name = players [ Math . floor ( Math . random ( ) * players . length ) ] ;
await skills . goToPlayer ( bot , player _name ) ;
await new Promise ( r => setTimeout ( r , 1000 ) ) ; ` ;
this . history . events . push ( [ 'finished_executing' , this . executeCode , 'default' ] ) ;
// this.history.events.push(['finished_executing', this.sendThought, 'What should I do next? I will make a plan and execute it.']);
this . history . events . push ( [ 'health' , this . sendThought , 'I may be under attack or need to eat! I will stop what I am doing to check my health and take action.' ] ) ;
this . history . events . push ( [ 'sunrise' , null , null ] ) ;
this . history . events . push ( [ 'noon' , null , null ] ) ;
this . history . events . push ( [ 'sunset' , null , null ] ) ;
this . history . events . push ( [ 'midnight' , null , null ] ) ;
}
2023-11-07 09:44:56 -06:00
this . bot . on ( 'login' , ( ) => {
this . bot . chat ( 'Hello world! I am ' + this . name ) ;
console . log ( ` ${ this . name } logged in. ` ) ;
} ) ;
2023-12-04 23:26:21 -08:00
for ( let [ event , callback , params ] of this . history . events ) {
if ( callback != null )
this . bot . on ( event , callback . bind ( this , params ) ) ;
}
2023-11-15 13:18:38 -08:00
}
async start ( ) {
await this . history . loadExamples ( ) ;
2023-11-07 09:44:56 -06:00
this . bot . on ( 'chat' , ( username , message ) => {
if ( username === this . name ) return ;
console . log ( 'received message from' , username , ':' , message ) ;
2023-12-04 23:26:21 -08:00
this . history . add ( username , message ) ;
this . handleMessage ( ) ;
2023-11-07 09:44:56 -06:00
} ) ;
2023-11-08 21:05:18 -08:00
2023-12-04 23:26:21 -08:00
this . bot . on ( 'time' , ( ) => {
if ( this . bot . time . timeOfDay == 0 )
this . bot . emit ( 'sunrise' ) ;
else if ( this . bot . time . timeOfDay == 6000 )
this . bot . emit ( 'noon' ) ;
else if ( this . bot . time . timeOfDay == 12000 )
this . bot . emit ( 'sunset' ) ;
else if ( this . bot . time . timeOfDay == 18000 )
this . bot . emit ( 'midnight' ) ;
} ) ;
if ( this . history . default ) {
this . executeCode ( this . history . default ) ;
}
}
async sendThought ( message ) {
this . history . add ( this . name , message ) ;
await this . handleMessage ( ) ;
2023-11-07 09:44:56 -06:00
}
2023-12-04 23:26:21 -08:00
async executeCode ( code , triesRemaining = 5 ) {
if ( code == 'default' )
code = this . history . default ;
if ( code ) {
this . coder . queueCode ( code ) ;
let code _return = await this . coder . execute ( ) ;
let message = code _return . message ;
if ( code _return . interrupted )
return ;
if ( ! code _return . success )
message += "\n Write code to fix the problem and try again." ;
console . log ( 'code return:' , message ) ;
this . history . add ( 'system' , message ) ;
if ( ! code _return . success )
await this . handleMessage ( triesRemaining - 1 ) ;
}
}
async handleMessage ( triesRemaining = 5 ) {
if ( triesRemaining == 0 ) {
console . log ( 'Quitting response loop.' ) ;
return ;
}
let res = await sendRequest ( this . history . getHistory ( ) , this . history . getSystemMessage ( ) ) ;
this . history . add ( this . name , res ) ;
let query _cmd = containsQuery ( res ) ;
if ( query _cmd ) { // contains query
let message = res . substring ( 0 , res . indexOf ( query _cmd ) ) . trim ( ) ;
if ( message )
this . bot . chat ( message ) ;
let query = getQuery ( query _cmd ) ;
let query _res = query . perform ( this ) ;
console . log ( 'Agent used query:' , query _cmd , 'and got:' , query _res )
this . history . add ( 'system' , query _res ) ;
await this . handleMessage ( triesRemaining - 1 ) ;
}
else if ( containsCodeBlock ( res ) ) { // contains code block
console . log ( 'Agent is executing code:' , res )
let message = res . substring ( 0 , res . indexOf ( '```' ) ) . trim ( ) ;
if ( message )
this . bot . chat ( message ) ;
let code = res . substring ( res . indexOf ( '```' ) + 3 , res . lastIndexOf ( '```' ) ) ;
await this . executeCode ( code , triesRemaining ) ;
}
else { // conversation response
this . bot . chat ( res ) ;
console . log ( 'Purely conversational response:' , res )
2023-11-07 09:44:56 -06:00
}
2023-12-04 23:26:21 -08:00
this . history . save ( ) ;
2023-11-07 09:44:56 -06:00
}
}