44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
from pathlib import Path
|
|
import sys
|
|
import importlib.util
|
|
from typing import Type
|
|
|
|
def load_source_as_module(source):
|
|
i = 0
|
|
while (module_name := f'mod_{i}') in sys.modules:
|
|
i += 1
|
|
|
|
spec = importlib.util.spec_from_file_location(module_name, source)
|
|
assert spec, f'Failed to load {source} as module'
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[module_name] = module
|
|
assert spec.loader, f'{source} spec has no loader'
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
def load_module(f: str):
|
|
if f.endswith('.py'):
|
|
sys.path.insert(0, str(Path(f).parent))
|
|
|
|
return load_source_as_module(f)
|
|
else:
|
|
return importlib.import_module(f)
|
|
|
|
def collect_functions(module):
|
|
for k in dir(module):
|
|
if k.startswith('_'):
|
|
continue
|
|
if k == k.capitalize():
|
|
continue
|
|
v = getattr(module, k)
|
|
if not callable(v) or isinstance(v, type):
|
|
continue
|
|
if not hasattr(v, '__annotations__'):
|
|
continue
|
|
|
|
vt = type(v)
|
|
if vt.__module__ == 'langchain_core.tools' and vt.__name__.endswith('Tool') and hasattr(v, 'func') and callable(v.func):
|
|
v = v.func
|
|
|
|
yield v
|