@@ -288,65 +288,73 @@ def __init__(
288
288
):
289
289
# Forward other arguments to parent class
290
290
super ().__init__ (* args , ** kwargs )
291
-
291
+
292
292
# Set default root directory to current working directory if not provided
293
293
self .root_dir = root_dir or os .getcwd ()
294
-
295
- self .log .info (f"LocalPersonaLoader initialized with root directory: { self .root_dir } " )
294
+
295
+ self .log .info (
296
+ f"LocalPersonaLoader initialized with root directory: { self .root_dir } "
297
+ )
296
298
297
299
def load_persona_classes (self ) -> list [type [BasePersona ]]:
298
300
"""
299
301
Loads persona classes from Python files in the local filesystem.
300
-
302
+
301
303
Scans the root_dir for .py files, dynamically imports them, and extracts
302
304
any class declarations that are subclasses of BasePersona.
303
305
"""
304
306
persona_classes : list [type [BasePersona ]] = []
305
-
307
+
306
308
# Check if root directory exists
307
309
if not os .path .exists (self .root_dir ):
308
310
self .log .info (f"Root directory does not exist: { self .root_dir } " )
309
311
return persona_classes
310
-
312
+
311
313
# Find all .py files in the root directory that contain "persona" in the name
312
314
all_py_files = glob (os .path .join (self .root_dir , "*.py" ))
313
315
py_files = [f for f in all_py_files if "persona" in Path (f ).stem .lower ()]
314
-
316
+
315
317
if not py_files :
316
- self .log .info (f"No Python files with 'persona' in the name found in directory: { self .root_dir } " )
318
+ self .log .info (
319
+ f"No Python files with 'persona' in the name found in directory: { self .root_dir } "
320
+ )
317
321
return persona_classes
318
-
319
- self .log .info (f"Found { len (py_files )} Python files with 'persona' in the name in { self .root_dir } " )
322
+
323
+ self .log .info (
324
+ f"Found { len (py_files )} Python files with 'persona' in the name in { self .root_dir } "
325
+ )
320
326
self .log .info ("PENDING: Loading persona classes from local Python files..." )
321
327
start_time_ns = time_ns ()
322
-
328
+
323
329
for py_file in py_files :
324
330
try :
325
331
# Get module name from file path
326
332
module_name = Path (py_file ).stem
327
-
333
+
328
334
# Skip if module name starts with underscore (private modules)
329
- if module_name .startswith ('_' ):
335
+ if module_name .startswith ("_" ):
330
336
continue
331
-
337
+
332
338
# Create module spec and load the module
333
339
spec = importlib .util .spec_from_file_location (module_name , py_file )
334
340
if spec is None or spec .loader is None :
335
341
self .log .warning (f" - Unable to create module spec for { py_file } " )
336
342
continue
337
-
343
+
338
344
module = importlib .util .module_from_spec (spec )
339
345
spec .loader .exec_module (module )
340
-
346
+
341
347
# Find all classes in the module that are BasePersona subclasses
342
348
module_persona_classes = []
343
349
for name , obj in inspect .getmembers (module , inspect .isclass ):
344
350
# Check if it's a subclass of BasePersona but not BasePersona itself
345
- if (issubclass (obj , BasePersona ) and
346
- obj is not BasePersona and
347
- obj .__module__ == module_name ):
351
+ if (
352
+ issubclass (obj , BasePersona )
353
+ and obj is not BasePersona
354
+ and obj .__module__ == module_name
355
+ ):
348
356
module_persona_classes .append (obj )
349
-
357
+
350
358
if module_persona_classes :
351
359
persona_classes .extend (module_persona_classes )
352
360
class_names = [cls .__name__ for cls in module_persona_classes ]
@@ -355,21 +363,21 @@ def load_persona_classes(self) -> list[type[BasePersona]]:
355
363
)
356
364
else :
357
365
self .log .debug (f" - No persona classes found in '{ py_file } '" )
358
-
366
+
359
367
except Exception :
360
368
# On exception, log an error and continue
361
369
# This mirrors the error handling pattern from entry point loading
362
370
self .log .exception (
363
371
f" - Unable to load persona classes from '{ py_file } ' due to an exception printed below."
364
372
)
365
373
continue
366
-
374
+
367
375
if len (persona_classes ) > 0 :
368
376
elapsed_time_ms = (time_ns () - start_time_ns ) // 1_000_000
369
377
self .log .info (
370
378
f"SUCCESS: Loaded { len (persona_classes )} persona classes from local filesystem. Time elapsed: { elapsed_time_ms } ms."
371
379
)
372
380
else :
373
381
self .log .info ("No persona classes found in local filesystem." )
374
-
382
+
375
383
return persona_classes
0 commit comments