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-07 09:44:56 -06:00
import { getQuery , containsQuery , getQueryDocs } from './utils/queries.js' ;
2023-11-07 12:00:55 -06:00
import { getSkillDocs , containsCodeBlock } from './utils/skill_library.js' ;
2023-11-07 09:44:56 -06:00
export class Agent {
constructor ( name ) {
this . name = name ;
this . system _message = ` You are a playful Minecraft bot named ' ${ name } ' that can communicate with players, see, move, mine, build, and interact with the world by writing and executing code.
2023-11-07 12:00:55 -06:00
Act human - like as if you were a typical Minecraft player , rather than an AI . Be brief in your responses , omit needless words , and do not give instructions unless asked . ` ;
2023-11-07 09:44:56 -06:00
this . system _message += getQueryDocs ( ) ;
this . system _message += getSkillDocs ( ) ;
2023-11-12 14:53:23 -08:00
this . current _system _message = this . system _message ;
2023-11-07 09:44:56 -06:00
2023-11-07 12:00:55 -06:00
this . bot = initBot ( name ) ;
2023-11-07 09:44:56 -06:00
this . history = new History ( this ) ;
2023-11-07 12:00:55 -06:00
this . coder = new Coder ( this ) ;
2023-11-12 14:53:23 -08:00
this . history . load ( ) ;
this . updateSystemMessage ( ) ;
2023-11-07 12:00:55 -06:00
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. ` ) ;
} ) ;
this . bot . on ( 'chat' , ( username , message ) => {
if ( username === this . name ) return ;
console . log ( 'received message from' , username , ':' , message ) ;
this . respond ( username , message ) ;
2023-11-12 14:53:23 -08:00
this . history . save ( ) ;
this . updateSystemMessage ( ) ;
2023-11-07 09:44:56 -06:00
} ) ;
2023-11-08 21:05:18 -08:00
this . bot . on ( 'finished_executing' , ( ) => {
setTimeout ( ( ) => {
if ( ! this . coder . executing ) {
// return to default behavior
}
} , 10000 ) ;
} )
2023-11-07 09:44:56 -06:00
}
2023-11-12 14:53:23 -08:00
updateSystemMessage ( ) {
if ( this . history . bio != '' ) {
this . current _system _message = this . system _message + '\n\nBio:\n' + this . history . bio ;
}
if ( this . history . memory != '' ) {
this . current _system _message = this . current _system _message + '\n\nMemories:\n' + this . history . memory ;
}
if ( this . history . knowledge != '' ) {
this . current _system _message = this . current _system _message + '\n\nKnowledge:\n' + this . history . knowledge ;
}
}
2023-11-07 09:44:56 -06:00
async respond ( username , message ) {
this . history . add ( username , message ) ;
for ( let i = 0 ; i < 5 ; i ++ ) {
2023-11-12 14:53:23 -08:00
let res = await sendRequest ( this . history . getHistory ( ) , this . current _system _message ) ;
2023-11-07 09:44:56 -06:00
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 ) ;
2023-11-07 12:00:55 -06:00
let query _res = query . perform ( this ) ;
2023-11-13 00:57:20 -06:00
console . log ( 'Agent used query:' , query _cmd , 'and got:' , query _res )
2023-11-12 13:57:22 -06:00
this . history . add ( 'system' , query _res ) ;
2023-11-07 09:44:56 -06:00
}
else if ( containsCodeBlock ( res ) ) { // contains code block
2023-11-13 00:57:20 -06:00
console . log ( 'Agent is executing code:' , res )
2023-11-07 09:44:56 -06:00
let message = res . substring ( 0 , res . indexOf ( '```' ) ) . trim ( ) ;
if ( message )
this . bot . chat ( message ) ;
let code = res . substring ( res . indexOf ( '```' ) + 3 , res . lastIndexOf ( '```' ) ) ;
if ( code ) {
2023-11-07 12:00:55 -06:00
this . coder . queueCode ( code ) ;
2023-11-07 20:21:19 -08:00
let code _return = await this . coder . execute ( ) ;
2023-11-12 13:57:22 -06:00
let message = code _return . message ;
2023-11-13 11:09:37 -06:00
if ( code _return . interrupted )
break ; // can only be interrupted by another chat, so this chat is over.
2023-11-12 13:57:22 -06:00
if ( ! code _return . success ) {
2023-11-07 20:21:19 -08:00
message += "\n Write code to fix the problem and try again." ;
}
2023-11-12 13:57:22 -06:00
console . log ( 'code return:' , message ) ;
this . history . add ( 'system' , message ) ;
2023-11-07 09:44:56 -06:00
}
}
else { // conversation response
this . bot . chat ( res ) ;
2023-11-13 00:57:20 -06:00
console . log ( 'Purely conversational response:' , res )
2023-11-07 09:44:56 -06:00
break ;
}
}
}
}