1
1
import { PostgresDatabaseAdapter } from "@ai16z/adapter-postgres" ;
2
2
import { SqliteDatabaseAdapter } from "@ai16z/adapter-sqlite" ;
3
- import { AutoClientInterface } from "@ai16z/client-auto" ;
4
- import { DirectClientInterface } from "@ai16z/client-direct" ;
5
3
import { DiscordClientInterface } from "@ai16z/client-discord" ;
6
- import { TelegramClientInterface } from "@ai16z/client-telegram" ;
7
4
import { TwitterClientInterface } from "@ai16z/client-twitter" ;
8
- import { FarcasterAgentClient } from "@ai16z/client-farcaster" ;
5
+ import { createNodePlugin } from "@ai16z/plugin-node" ;
6
+ import { evmPlugin } from "@ai16z/plugin-evm" ;
7
+ import { bootstrapPlugin } from "@ai16z/plugin-bootstrap" ;
8
+ import { imageGenerationPlugin } from "@ai16z/plugin-image-generation" ;
9
9
import {
10
10
AgentRuntime ,
11
11
CacheManager ,
12
12
Character ,
13
- Clients ,
14
13
DbCacheAdapter ,
15
14
FsCacheAdapter ,
16
15
IAgentRuntime ,
@@ -24,32 +23,14 @@ import {
24
23
stringToUuid ,
25
24
validateCharacterConfig ,
26
25
} from "@ai16z/eliza" ;
27
- import { zgPlugin } from "@ai16z/plugin-0g" ;
28
26
import createGoatPlugin from "@ai16z/plugin-goat" ;
29
- import { bootstrapPlugin } from "@ai16z/plugin-bootstrap" ;
30
- // import { intifacePlugin } from "@ai16z/plugin-intiface";
31
- import {
32
- coinbaseCommercePlugin ,
33
- coinbaseMassPaymentsPlugin ,
34
- tradePlugin ,
35
- tokenContractPlugin ,
36
- webhookPlugin ,
37
- advancedTradePlugin ,
38
- } from "@ai16z/plugin-coinbase" ;
39
- import { confluxPlugin } from "@ai16z/plugin-conflux" ;
40
- import { imageGenerationPlugin } from "@ai16z/plugin-image-generation" ;
41
- import { evmPlugin } from "@ai16z/plugin-evm" ;
42
- import { createNodePlugin } from "@ai16z/plugin-node" ;
43
- import { solanaPlugin } from "@ai16z/plugin-solana" ;
44
- import { teePlugin , TEEMode } from "@ai16z/plugin-tee" ;
45
- import { aptosPlugin , TransferAptosToken } from "@ai16z/plugin-aptos" ;
46
- import { flowPlugin } from "@ai16z/plugin-flow" ;
47
27
import Database from "better-sqlite3" ;
48
28
import fs from "fs" ;
49
29
import path from "path" ;
50
30
import readline from "readline" ;
51
31
import { fileURLToPath } from "url" ;
52
32
import yargs from "yargs" ;
33
+ import { DirectClient } from "@ai16z/client-direct" ;
53
34
54
35
const __filename = fileURLToPath ( import . meta. url ) ; // get the resolved path to the file
55
36
const __dirname = path . dirname ( __filename ) ; // get the name of the directory
@@ -198,6 +179,7 @@ export async function loadCharacters(
198
179
return loadedCharacters ;
199
180
}
200
181
182
+ // v2 TODO: should be a registered pattern to get the registered token from the plugin being used
201
183
export function getTokenForProvider (
202
184
provider : ModelProviderName ,
203
185
character : Character
@@ -276,24 +258,10 @@ export function getTokenForProvider(
276
258
character . settings ?. secrets ?. VOLENGINE_API_KEY ||
277
259
settings . VOLENGINE_API_KEY
278
260
) ;
279
- case ModelProviderName . NANOGPT :
280
- return (
281
- character . settings ?. secrets ?. NANOGPT_API_KEY ||
282
- settings . NANOGPT_API_KEY
283
- ) ;
284
- case ModelProviderName . HYPERBOLIC :
285
- return (
286
- character . settings ?. secrets ?. HYPERBOLIC_API_KEY ||
287
- settings . HYPERBOLIC_API_KEY
288
- ) ;
289
- case ModelProviderName . VENICE :
290
- return (
291
- character . settings ?. secrets ?. VENICE_API_KEY ||
292
- settings . VENICE_API_KEY
293
- ) ;
294
261
}
295
262
}
296
263
264
+ // v2 TODO: should be a registered pattern to get the database adapter being used
297
265
function initializeDatabase ( dataDir : string ) {
298
266
if ( process . env . POSTGRES_URL ) {
299
267
elizaLogger . info ( "Initializing PostgreSQL connection..." ) ;
@@ -331,41 +299,23 @@ export async function initializeClients(
331
299
// each client can only register once
332
300
// and if we want two we can explicitly support it
333
301
const clients : Record < string , any > = { } ;
334
- const clientTypes :string [ ] =
302
+ const clientTypes : string [ ] =
335
303
character . clients ?. map ( ( str ) => str . toLowerCase ( ) ) || [ ] ;
336
- elizaLogger . log ( 'initializeClients' , clientTypes , 'for' , character . name )
337
-
338
- if ( clientTypes . includes ( "auto" ) ) {
339
- const autoClient = await AutoClientInterface . start ( runtime ) ;
340
- if ( autoClient ) clients . auto = autoClient ;
341
- }
304
+ elizaLogger . log ( "initializeClients" , clientTypes , "for" , character . name ) ;
342
305
306
+ // v2 TODO: Instead of checking if client type includes "discord" or "twitter", should just be a loop and hook
307
+ // So we don't need to check per platform
343
308
if ( clientTypes . includes ( "discord" ) ) {
344
309
const discordClient = await DiscordClientInterface . start ( runtime ) ;
345
310
if ( discordClient ) clients . discord = discordClient ;
346
311
}
347
312
348
- if ( clientTypes . includes ( "telegram" ) ) {
349
- const telegramClient = await TelegramClientInterface . start ( runtime ) ;
350
- if ( telegramClient ) clients . telegram = telegramClient ;
351
- }
352
-
353
313
if ( clientTypes . includes ( "twitter" ) ) {
354
- TwitterClientInterface . enableSearch = ! isFalsish ( getSecret ( character , "TWITTER_SEARCH_ENABLE" ) ) ;
355
314
const twitterClient = await TwitterClientInterface . start ( runtime ) ;
356
315
if ( twitterClient ) clients . twitter = twitterClient ;
357
316
}
358
317
359
- if ( clientTypes . includes ( "farcaster" ) ) {
360
- // why is this one different :(
361
- const farcasterClient = new FarcasterAgentClient ( runtime ) ;
362
- if ( farcasterClient ) {
363
- farcasterClient . start ( ) ;
364
- clients . farcaster = farcasterClient ;
365
- }
366
- }
367
-
368
- elizaLogger . log ( 'client keys' , Object . keys ( clients ) ) ;
318
+ elizaLogger . log ( "client keys" , Object . keys ( clients ) ) ;
369
319
370
320
if ( character . plugins ?. length > 0 ) {
371
321
for ( const plugin of character . plugins ) {
@@ -381,22 +331,6 @@ export async function initializeClients(
381
331
return clients ;
382
332
}
383
333
384
- function isFalsish ( input : any ) : boolean {
385
- // If the input is exactly NaN, return true
386
- if ( Number . isNaN ( input ) ) {
387
- return true ;
388
- }
389
-
390
- // Convert input to a string if it's not null or undefined
391
- const value = input == null ? '' : String ( input ) ;
392
-
393
- // List of common falsish string representations
394
- const falsishValues = [ 'false' , '0' , 'no' , 'n' , 'off' , 'null' , 'undefined' , '' ] ;
395
-
396
- // Check if the value (trimmed and lowercased) is in the falsish list
397
- return falsishValues . includes ( value . trim ( ) . toLowerCase ( ) ) ;
398
- }
399
-
400
334
function getSecret ( character : Character , secret : string ) {
401
335
return character . settings ?. secrets ?. [ secret ] || process . env [ secret ] ;
402
336
}
@@ -408,7 +342,7 @@ export async function createAgent(
408
342
db : IDatabaseAdapter ,
409
343
cache : ICacheManager ,
410
344
token : string
411
- ) :AgentRuntime {
345
+ ) : Promise < AgentRuntime > {
412
346
elizaLogger . success (
413
347
elizaLogger . successesTitle ,
414
348
"Creating runtime for character" ,
@@ -417,17 +351,6 @@ export async function createAgent(
417
351
418
352
nodePlugin ??= createNodePlugin ( ) ;
419
353
420
- const teeMode = getSecret ( character , "TEE_MODE" ) || "OFF" ;
421
- const walletSecretSalt = getSecret ( character , "WALLET_SECRET_SALT" ) ;
422
-
423
- // Validate TEE configuration
424
- if ( teeMode !== TEEMode . OFF && ! walletSecretSalt ) {
425
- elizaLogger . error (
426
- "WALLET_SECRET_SALT required when TEE_MODE is enabled"
427
- ) ;
428
- throw new Error ( "Invalid TEE configuration" ) ;
429
- }
430
-
431
354
let goatPlugin : any | undefined ;
432
355
if ( getSecret ( character , "ALCHEMY_API_KEY" ) ) {
433
356
goatPlugin = await createGoatPlugin ( ( secret ) =>
@@ -444,53 +367,19 @@ export async function createAgent(
444
367
// character.plugins are handled when clients are added
445
368
plugins : [
446
369
bootstrapPlugin ,
447
- getSecret ( character , "CONFLUX_CORE_PRIVATE_KEY" )
448
- ? confluxPlugin
449
- : null ,
450
370
nodePlugin ,
451
- getSecret ( character , "SOLANA_PUBLIC_KEY" ) ||
452
- ( getSecret ( character , "WALLET_PUBLIC_KEY" ) &&
453
- ! getSecret ( character , "WALLET_PUBLIC_KEY" ) ?. startsWith ( "0x" ) )
454
- ? solanaPlugin
455
- : null ,
456
371
getSecret ( character , "EVM_PRIVATE_KEY" ) ||
457
372
( getSecret ( character , "WALLET_PUBLIC_KEY" ) &&
458
373
getSecret ( character , "WALLET_PUBLIC_KEY" ) ?. startsWith ( "0x" ) )
459
374
? evmPlugin
460
375
: null ,
461
- getSecret ( character , "ZEROG_PRIVATE_KEY" ) ? zgPlugin : null ,
462
- getSecret ( character , "COINBASE_COMMERCE_KEY" )
463
- ? coinbaseCommercePlugin
464
- : null ,
465
376
getSecret ( character , "FAL_API_KEY" ) ||
466
377
getSecret ( character , "OPENAI_API_KEY" ) ||
467
378
getSecret ( character , "VENICE_API_KEY" ) ||
468
379
getSecret ( character , "HEURIST_API_KEY" )
469
380
? imageGenerationPlugin
470
381
: null ,
471
- ...( getSecret ( character , "COINBASE_API_KEY" ) &&
472
- getSecret ( character , "COINBASE_PRIVATE_KEY" )
473
- ? [
474
- coinbaseMassPaymentsPlugin ,
475
- tradePlugin ,
476
- tokenContractPlugin ,
477
- advancedTradePlugin ,
478
- ]
479
- : [ ] ) ,
480
- ...( teeMode !== TEEMode . OFF && walletSecretSalt
481
- ? [ teePlugin , solanaPlugin ]
482
- : [ ] ) ,
483
- getSecret ( character , "COINBASE_API_KEY" ) &&
484
- getSecret ( character , "COINBASE_PRIVATE_KEY" ) &&
485
- getSecret ( character , "COINBASE_NOTIFICATION_URI" )
486
- ? webhookPlugin
487
- : null ,
488
382
getSecret ( character , "ALCHEMY_API_KEY" ) ? goatPlugin : null ,
489
- getSecret ( character , "FLOW_ADDRESS" ) &&
490
- getSecret ( character , "FLOW_PRIVATE_KEY" )
491
- ? flowPlugin
492
- : null ,
493
- getSecret ( character , "APTOS_PRIVATE_KEY" ) ? aptosPlugin : null ,
494
383
] . filter ( Boolean ) ,
495
384
providers : [ ] ,
496
385
actions : [ ] ,
@@ -513,7 +402,10 @@ function initializeDbCache(character: Character, db: IDatabaseCacheAdapter) {
513
402
return cache ;
514
403
}
515
404
516
- async function startAgent ( character : Character , directClient ) :AgentRuntime {
405
+ async function startAgent (
406
+ character : Character ,
407
+ directClient
408
+ ) : Promise < AgentRuntime > {
517
409
let db : IDatabaseAdapter & IDatabaseCacheAdapter ;
518
410
try {
519
411
character . id ??= stringToUuid ( character . name ) ;
@@ -532,19 +424,24 @@ async function startAgent(character: Character, directClient):AgentRuntime {
532
424
await db . init ( ) ;
533
425
534
426
const cache = initializeDbCache ( character , db ) ;
535
- const runtime :AgentRuntime = await createAgent ( character , db , cache , token ) ;
427
+ const runtime : AgentRuntime = await createAgent (
428
+ character ,
429
+ db ,
430
+ cache ,
431
+ token
432
+ ) ;
536
433
537
434
// start services/plugins/process knowledge
538
435
await runtime . initialize ( ) ;
539
436
540
437
// start assigned clients
541
438
runtime . clients = await initializeClients ( character , runtime ) ;
542
439
543
- // add to container
544
440
directClient . registerAgent ( runtime ) ;
441
+ console . log ( "registered agent" ) ;
545
442
546
443
// report to console
547
- elizaLogger . debug ( `Started ${ character . name } as ${ runtime . agentId } ` )
444
+ elizaLogger . debug ( `Started ${ character . name } as ${ runtime . agentId } ` ) ;
548
445
549
446
return runtime ;
550
447
} catch ( error ) {
@@ -561,7 +458,8 @@ async function startAgent(character: Character, directClient):AgentRuntime {
561
458
}
562
459
563
460
const startAgents = async ( ) => {
564
- const directClient = await DirectClientInterface . start ( ) ;
461
+ const dc = new DirectClient ( ) ;
462
+ await dc . start ( parseInt ( settings . SERVER_PORT || "3000" ) ) ;
565
463
const args = parseArguments ( ) ;
566
464
567
465
let charactersArg = args . characters || args . character ;
@@ -574,20 +472,16 @@ const startAgents = async () => {
574
472
575
473
try {
576
474
for ( const character of characters ) {
577
- await startAgent ( character , directClient ) ;
475
+ await startAgent ( character , dc ) ;
578
476
}
579
477
} catch ( error ) {
580
478
elizaLogger . error ( "Error starting agents:" , error ) ;
581
479
}
582
- // upload some agent functionality into directClient
583
- directClient . startAgent = async character => {
584
- // wrap it so we don't have to inject directClient later
585
- return startAgent ( character , directClient )
586
- } ;
587
480
588
481
function chat ( ) {
589
482
const agentId = characters [ 0 ] . name ?? "Agent" ;
590
483
rl . question ( "You: " , async ( input ) => {
484
+ console . log ( "input" , input ) ;
591
485
await handleUserInput ( input , agentId ) ;
592
486
if ( input . toLowerCase ( ) !== "exit" ) {
593
487
chat ( ) ; // Loop back to ask another question
@@ -617,8 +511,9 @@ async function handleUserInput(input, agentId) {
617
511
}
618
512
619
513
try {
514
+ console . log ( "input" , input ) ;
620
515
const serverPort = parseInt ( settings . SERVER_PORT || "3000" ) ;
621
-
516
+ console . log ( "send message" ) ;
622
517
const response = await fetch (
623
518
`http://localhost:${ serverPort } /${ agentId } /message` ,
624
519
{
0 commit comments