4
4
AgentRuntime ,
5
5
CacheManager ,
6
6
CacheStore ,
7
+ type Plugin ,
7
8
type Character ,
8
9
type ClientInstance ,
9
10
DbCacheAdapter ,
@@ -21,6 +22,7 @@ import {
21
22
import { defaultCharacter } from "./defaultCharacter.ts" ;
22
23
23
24
import { bootstrapPlugin } from "@elizaos/plugin-bootstrap" ;
25
+ import JSON5 from 'json5' ;
24
26
25
27
import fs from "fs" ;
26
28
import net from "net" ;
@@ -62,7 +64,7 @@ export function parseArguments(): {
62
64
} )
63
65
. parseSync ( ) ;
64
66
} catch ( error ) {
65
- elizaLogger . error ( "Error parsing arguments:" , error ) ;
67
+ console . error ( "Error parsing arguments:" , error ) ;
66
68
return { } ;
67
69
}
68
70
}
@@ -116,7 +118,7 @@ export async function loadCharacterFromOnchain(): Promise<Character[]> {
116
118
if (!jsonText) return [];
117
119
const loadedCharacters = [];
118
120
try {
119
- const character = JSON .parse(jsonText);
121
+ const character = JSON5 .parse(jsonText);
120
122
validateCharacterConfig(character);
121
123
122
124
// .id isn't really valid
@@ -182,7 +184,7 @@ async function loadCharactersFromUrl(url: string): Promise<Character[]> {
182
184
}
183
185
return characters ;
184
186
} catch ( e ) {
185
- elizaLogger . error ( `Error loading character(s) from ${ url } : ${ e } ` ) ;
187
+ console . error ( `Error loading character(s) from ${ url } : ` , e ) ;
186
188
process . exit ( 1 ) ;
187
189
}
188
190
}
@@ -213,6 +215,15 @@ async function jsonToCharacter(
213
215
}
214
216
// Handle plugins
215
217
character . plugins = await handlePluginImporting ( character . plugins ) ;
218
+ elizaLogger . info ( character . name , 'loaded plugins:' , "[\n " + character . plugins . map ( p => `"${ p . npmName } "` ) . join ( ", \n " ) + "\n]" ) ;
219
+
220
+ // Handle Post Processors plugins
221
+ if ( character . postProcessors ?. length > 0 ) {
222
+ elizaLogger . info ( character . name , 'loading postProcessors' , character . postProcessors ) ;
223
+ character . postProcessors = await handlePluginImporting ( character . postProcessors ) ;
224
+ }
225
+
226
+ // Handle extends
216
227
if ( character . extends ) {
217
228
elizaLogger . info (
218
229
`Merging ${ character . name } character with parent characters`
@@ -235,7 +246,7 @@ async function loadCharacter(filePath: string): Promise<Character> {
235
246
if ( ! content ) {
236
247
throw new Error ( `Character file not found: ${ filePath } ` ) ;
237
248
}
238
- const character = JSON . parse ( content ) ;
249
+ const character = JSON5 . parse ( content ) ;
239
250
return jsonToCharacter ( filePath , character ) ;
240
251
}
241
252
@@ -258,7 +269,7 @@ async function loadCharacterTryPath(characterPath: string): Promise<Character> {
258
269
) , // relative to project root characters dir
259
270
] ;
260
271
261
- elizaLogger . info (
272
+ elizaLogger . debug (
262
273
"Trying paths:" ,
263
274
pathsToTry . map ( ( p ) => ( {
264
275
path : p ,
@@ -286,10 +297,10 @@ async function loadCharacterTryPath(characterPath: string): Promise<Character> {
286
297
}
287
298
try {
288
299
const character : Character = await loadCharacter ( resolvedPath ) ;
289
- elizaLogger . info ( `Successfully loaded character from: ${ resolvedPath } ` ) ;
300
+ elizaLogger . success ( `Successfully loaded character from: ${ resolvedPath } ` ) ;
290
301
return character ;
291
302
} catch ( e ) {
292
- elizaLogger . error ( `Error parsing character from ${ resolvedPath } : ${ e } ` ) ;
303
+ console . error ( `Error parsing character from ${ resolvedPath } : ` , e ) ;
293
304
throw new Error ( `Error parsing character from ${ resolvedPath } : ${ e } ` ) ;
294
305
}
295
306
}
@@ -360,30 +371,35 @@ export async function loadCharacters(
360
371
361
372
async function handlePluginImporting ( plugins : string [ ] ) {
362
373
if ( plugins . length > 0 ) {
363
- elizaLogger . info ( "Plugins are: " , plugins ) ;
374
+ // this logging should happen before calling, so we can include important context
375
+ //elizaLogger.info("Plugins are: ", plugins);
364
376
const importedPlugins = await Promise . all (
365
377
plugins . map ( async ( plugin ) => {
366
378
try {
367
- const importedPlugin = await import ( plugin ) ;
379
+ const importedPlugin : Plugin = await import ( plugin ) ;
368
380
const functionName =
369
381
plugin
370
382
. replace ( "@elizaos/plugin-" , "" )
371
383
. replace ( "@elizaos-plugins/plugin-" , "" )
372
384
. replace ( / - ./ g, ( x ) => x [ 1 ] . toUpperCase ( ) ) +
373
385
"Plugin" ; // Assumes plugin function is camelCased with Plugin suffix
374
- return (
386
+ if ( ! importedPlugin [ functionName ] && ! importedPlugin . default ) {
387
+ elizaLogger . warn ( plugin , 'does not have an default export or' , functionName )
388
+ }
389
+ return { ...(
375
390
importedPlugin . default || importedPlugin [ functionName ]
376
- ) ;
391
+ ) , npmName : plugin } ;
377
392
} catch ( importError ) {
378
- elizaLogger . error (
393
+ console . error (
379
394
`Failed to import plugin: ${ plugin } ` ,
380
395
importError
381
396
) ;
382
- return [ ] ; // Return null for failed imports
397
+ return false ; // Return null for failed imports
383
398
}
384
399
} )
385
- ) ;
386
- return importedPlugins ;
400
+ )
401
+ // remove plugins that failed to load, so agent can try to start
402
+ return importedPlugins . filter ( p => ! ! p ) ;
387
403
} else {
388
404
return [ ] ;
389
405
}
@@ -792,6 +808,26 @@ const hasValidRemoteUrls = () =>
792
808
process . env . REMOTE_CHARACTER_URLS !== "" &&
793
809
process . env . REMOTE_CHARACTER_URLS . startsWith ( "http" ) ;
794
810
811
+ /**
812
+ * Post processing of character after loading
813
+ * @param character
814
+ */
815
+ const handlePostCharacterLoaded = async ( character : Character ) : Promise < Character > => {
816
+ let processedCharacter = character ;
817
+ // Filtering the plugins with the method of handlePostCharacterLoaded
818
+ const processors = character ?. postProcessors ?. filter ( p => typeof p . handlePostCharacterLoaded === 'function' ) ;
819
+ if ( processors ?. length > 0 ) {
820
+ processedCharacter = Object . assign ( { } , character , { postProcessors : undefined } ) ;
821
+ // process the character with each processor
822
+ // the order is important, so we loop through the processors
823
+ for ( let i = 0 ; i < processors . length ; i ++ ) {
824
+ const processor = processors [ i ] ;
825
+ processedCharacter = await processor . handlePostCharacterLoaded ( processedCharacter ) ;
826
+ }
827
+ }
828
+ return processedCharacter ;
829
+ }
830
+
795
831
const startAgents = async ( ) => {
796
832
const directClient = new DirectClient ( ) ;
797
833
let serverPort = Number . parseInt ( settings . SERVER_PORT || "3000" ) ;
@@ -805,7 +841,8 @@ const startAgents = async () => {
805
841
806
842
try {
807
843
for ( const character of characters ) {
808
- await startAgent ( character , directClient ) ;
844
+ const processedCharacter = await handlePostCharacterLoaded ( character ) ;
845
+ await startAgent ( processedCharacter , directClient ) ;
809
846
}
810
847
} catch ( error ) {
811
848
elizaLogger . error ( "Error starting agents:" , error ) ;
@@ -824,9 +861,18 @@ const startAgents = async () => {
824
861
directClient . startAgent = async ( character ) => {
825
862
// Handle plugins
826
863
character . plugins = await handlePluginImporting ( character . plugins ) ;
864
+ elizaLogger . info ( character . name , 'loaded plugins:' , '[' + character . plugins . map ( p => `"${ p . npmName } "` ) . join ( ', ' ) + ']' ) ;
865
+
866
+ // Handle Post Processors plugins
867
+ if ( character . postProcessors ?. length > 0 ) {
868
+ elizaLogger . info ( character . name , 'loading postProcessors' , character . postProcessors ) ;
869
+ character . postProcessors = await handlePluginImporting ( character . postProcessors ) ;
870
+ }
871
+ // character's post processing
872
+ const processedCharacter = await handlePostCharacterLoaded ( character ) ;
827
873
828
874
// wrap it so we don't have to inject directClient later
829
- return startAgent ( character , directClient ) ;
875
+ return startAgent ( processedCharacter , directClient ) ;
830
876
} ;
831
877
832
878
directClient . loadCharacterTryPath = loadCharacterTryPath ;
@@ -835,7 +881,7 @@ const startAgents = async () => {
835
881
directClient . start ( serverPort ) ;
836
882
837
883
if ( serverPort !== Number . parseInt ( settings . SERVER_PORT || "3000" ) ) {
838
- elizaLogger . log ( `Server started on alternate port ${ serverPort } ` ) ;
884
+ elizaLogger . warn ( `Server started on alternate port ${ serverPort } ` ) ;
839
885
}
840
886
841
887
elizaLogger . info (
0 commit comments