UNPKG

agentlang

Version:

The easiest way to build the most reliable AI agents - enterprise-grade teams of AI agents that collaborate with each other and humans

143 lines (132 loc) 3.95 kB
import { logger } from './logger.js'; import { now, splitRefs } from './util.js'; import { isNodeEnv } from '../utils/runtime.js'; import { setModuleFnFetcher } from './defs.js'; let dirname: any = undefined; let sep: any = undefined; if (isNodeEnv) { const p = await import('path'); dirname = p.dirname; sep = p.sep; } else { sep = '/'; dirname = (s: string): string => { const idx = s.lastIndexOf(sep); if (idx > 0) { return s.substring(0, idx); } else { return s; } }; } const importedModules = new Map<string, any>(); // Usage: importModule("./mymodels/acme.js") export async function importModule(path: string, name: string, moduleFileName?: string) { if (isNodeEnv) { if (importedModules.has(name)) { logger.warn(`Alias '${name}' will overwrite a previously imported module`); } if (moduleFileName) { let s: string = dirname(moduleFileName); if (s.startsWith('./')) { s = s.substring(2); } else if (s == '.') { s = process.cwd(); } path = `${s}${sep}${path}`; } if (!(path.startsWith(sep) || path.startsWith('.'))) { path = process.cwd() + sep + path; } const m = await import(/* @vite-ignore */ path); importedModules.set(name, m); // e.g of dynamic fn-call: //// let f = eval("(a, b) => m.add(a, b)"); //// console.log(f(10, 20)) return m; } else { return {}; } } export function moduleImported(moduleName: string): boolean { return importedModules.has(moduleName); } function maybeEvalFunction(fnName: string): Function | undefined { try { return eval(fnName); } catch (reason: any) { logger.debug(reason); return undefined; } } async function invokeBuiltInFn(fnName: string, args: Array<any> | null, isAsync: boolean = false) { if (fnName == 'now') { return now(); } else if (fnName == 'uuid') { return crypto.randomUUID(); } else { const pf: Function | undefined = maybeEvalFunction(fnName); if (pf instanceof Function) { if (args === null) { if (isAsync) return await pf(); else return pf(); } else { if (isAsync) return await pf(...args.slice(0, args.length - 1)); else return pf(...args.slice(0, args.length - 1)); } } else { throw new Error(`Failed to invoke function - ${fnName}`); } } } export async function invokeModuleFn( fqFnName: string, args: Array<any> | null, isAsync: boolean = false ): Promise<any> { try { const refs: string[] = splitRefs(fqFnName); if (refs.length == 1) { if (isAsync) { return await invokeBuiltInFn(refs[0], args, isAsync); } else { return invokeBuiltInFn(refs[0], args); } } const mname = refs[0]; const m = importedModules.get(mname); if (m !== undefined) { const f = m[refs[1]]; if (f !== undefined) { if (args === null) if (isAsync) { return await f(); } else return f(); else if (isAsync) { return await f(...args); } else return f(...args); } else throw new Error(`Function not found - ${fqFnName}`); } else throw new Error(`JavaScript module ${refs[0]} not found`); } catch (reason: any) { const pf: Function | undefined = maybeEvalFunction(fqFnName); if (pf instanceof Function) { if (args === null) { if (isAsync) return await pf(); else return pf(); } else { if (isAsync) return await pf(...args.slice(0, args.length - 1)); else return pf(...args.slice(0, args.length - 1)); } } else { throw new Error(reason); } } } export function getModuleFn(fqFnName: string): Function | undefined { const refs: string[] = splitRefs(fqFnName); const m = importedModules.get(refs[0]); if (m !== undefined) { return m[refs[1]]; } else return undefined; } setModuleFnFetcher(getModuleFn);