agentlang 0.6.9 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/language/generated/ast.js +1 -0
- package/out/language/generated/ast.js.map +1 -1
- package/out/language/main.cjs.map +1 -1
- package/out/runtime/defs.d.ts +9 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +7 -0
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/jsmodules.d.ts +8 -0
- package/out/runtime/jsmodules.d.ts.map +1 -1
- package/out/runtime/jsmodules.js +139 -22
- package/out/runtime/jsmodules.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +3 -2
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/module-transform.d.ts +77 -0
- package/out/runtime/module-transform.d.ts.map +1 -0
- package/out/runtime/module-transform.js +201 -0
- package/out/runtime/module-transform.js.map +1 -0
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +18 -6
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/auth.d.ts.map +1 -1
- package/out/runtime/modules/auth.js +15 -2
- package/out/runtime/modules/auth.js.map +1 -1
- package/out/runtime/modules/core.d.ts.map +1 -1
- package/out/runtime/modules/core.js +11 -4
- package/out/runtime/modules/core.js.map +1 -1
- package/package.json +185 -186
- package/src/language/generated/ast.ts +1 -1
- package/src/runtime/defs.ts +20 -0
- package/src/runtime/jsmodules.ts +189 -22
- package/src/runtime/loader.ts +3 -2
- package/src/runtime/module-transform.ts +277 -0
- package/src/runtime/modules/ai.ts +20 -6
- package/src/runtime/modules/auth.ts +15 -2
- package/src/runtime/modules/core.ts +13 -3
- package/out/setupClassic.d.ts +0 -98
- package/out/setupClassic.d.ts.map +0 -1
- package/out/setupClassic.js +0 -38
- package/out/setupClassic.js.map +0 -1
- package/out/setupCommon.d.ts +0 -2
- package/out/setupCommon.d.ts.map +0 -1
- package/out/setupCommon.js +0 -33
- package/out/setupCommon.js.map +0 -1
- package/out/setupExtended.d.ts +0 -40
- package/out/setupExtended.d.ts.map +0 -1
- package/out/setupExtended.js +0 -67
- package/out/setupExtended.js.map +0 -1
package/src/runtime/jsmodules.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { logger } from './logger.js';
|
|
2
2
|
import { now, splitRefs } from './util.js';
|
|
3
3
|
import { isNodeEnv } from '../utils/runtime.js';
|
|
4
|
-
import { setModuleFnFetcher } from './defs.js';
|
|
4
|
+
import { setModuleFnFetcher, getModuleLoader } from './defs.js';
|
|
5
|
+
import {
|
|
6
|
+
transformModule,
|
|
7
|
+
wrapModuleCode,
|
|
8
|
+
evaluateModule,
|
|
9
|
+
wrapCommonJSCode,
|
|
10
|
+
evaluateCommonJS,
|
|
11
|
+
} from './module-transform.js';
|
|
5
12
|
|
|
6
13
|
let dirname: any = undefined;
|
|
7
14
|
let sep: any = undefined;
|
|
@@ -24,39 +31,199 @@ if (isNodeEnv) {
|
|
|
24
31
|
|
|
25
32
|
const importedModules = new Map<string, any>();
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Load dependencies for a module using the configured dependency provider
|
|
36
|
+
*/
|
|
37
|
+
async function loadModuleDependencies(
|
|
38
|
+
imports: Array<{ defaultImport?: string; namedImports?: string[]; moduleSpecifier: string }>
|
|
39
|
+
): Promise<Map<string, any>> {
|
|
40
|
+
const loadedDeps = new Map<string, any>();
|
|
41
|
+
|
|
42
|
+
for (const imp of imports) {
|
|
43
|
+
const moduleSpecifier = imp.moduleSpecifier;
|
|
44
|
+
|
|
45
|
+
logger.debug(`Loading dependency: ${moduleSpecifier}`);
|
|
46
|
+
|
|
47
|
+
// Try to get from dependency provider first
|
|
48
|
+
let module: any;
|
|
49
|
+
const moduleLoader = getModuleLoader();
|
|
50
|
+
if (moduleLoader?.dependencyProvider) {
|
|
51
|
+
module = moduleLoader.dependencyProvider(moduleSpecifier);
|
|
32
52
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
|
|
54
|
+
if (!module) {
|
|
55
|
+
// In browser without dependency provider, we can't load external modules
|
|
56
|
+
if (!isNodeEnv) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Failed to load dependency "${moduleSpecifier}". ` +
|
|
59
|
+
`Please add it to the dependency provider via setModuleLoader().`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// In Node.js, try dynamic import
|
|
64
|
+
try {
|
|
65
|
+
module = await import(/* @vite-ignore */ moduleSpecifier);
|
|
66
|
+
logger.debug(`Loaded ${moduleSpecifier} via dynamic import`);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
throw new Error(`Failed to load dependency "${moduleSpecifier}": ${error}`);
|
|
39
69
|
}
|
|
40
|
-
|
|
70
|
+
} else {
|
|
71
|
+
logger.debug(`Using pre-imported dependency: ${moduleSpecifier}`);
|
|
41
72
|
}
|
|
42
|
-
|
|
43
|
-
|
|
73
|
+
|
|
74
|
+
// Handle default import
|
|
75
|
+
if (imp.defaultImport) {
|
|
76
|
+
loadedDeps.set(imp.defaultImport, module.default || module);
|
|
44
77
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
78
|
+
|
|
79
|
+
// Handle named imports
|
|
80
|
+
if (imp.namedImports) {
|
|
81
|
+
for (const name of imp.namedImports) {
|
|
82
|
+
loadedDeps.set(name, module[name]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return loadedDeps;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Load a JavaScript module in the browser environment
|
|
92
|
+
*/
|
|
93
|
+
async function loadModuleInBrowser(
|
|
94
|
+
path: string,
|
|
95
|
+
name: string,
|
|
96
|
+
moduleFileName?: string
|
|
97
|
+
): Promise<any> {
|
|
98
|
+
const moduleLoader = getModuleLoader();
|
|
99
|
+
if (!moduleLoader) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'ModuleLoader not configured. Call setModuleLoader() with a fileReader and dependencyProvider.'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
logger.info(`Loading module in browser: ${path} as ${name}`);
|
|
106
|
+
|
|
107
|
+
// Resolve path relative to the module file
|
|
108
|
+
let resolvedPath = path;
|
|
109
|
+
if (moduleFileName) {
|
|
110
|
+
const dir = dirname(moduleFileName);
|
|
111
|
+
resolvedPath = dir ? `${dir}${sep}${path}` : path;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Add basePath if configured
|
|
115
|
+
if (moduleLoader.basePath) {
|
|
116
|
+
if (!resolvedPath.startsWith('/')) {
|
|
117
|
+
resolvedPath = `${moduleLoader.basePath}${sep}${resolvedPath}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
logger.debug(`Resolved path: ${resolvedPath}`);
|
|
122
|
+
|
|
123
|
+
// Read the module content
|
|
124
|
+
const content = await moduleLoader.fileReader(resolvedPath);
|
|
125
|
+
|
|
126
|
+
if (!content || content.trim().length === 0) {
|
|
127
|
+
logger.warn(`Module file ${resolvedPath} is empty`);
|
|
52
128
|
return {};
|
|
53
129
|
}
|
|
130
|
+
|
|
131
|
+
logger.debug(`Read ${content.length} characters from ${resolvedPath}`);
|
|
132
|
+
|
|
133
|
+
// Check if the file uses ES6 import syntax
|
|
134
|
+
const hasImports = /\bimport\s+/.test(content);
|
|
135
|
+
|
|
136
|
+
let moduleExports: any;
|
|
137
|
+
|
|
138
|
+
if (hasImports) {
|
|
139
|
+
logger.debug(`Processing ES6 imports for: ${name}`);
|
|
140
|
+
|
|
141
|
+
// Transform the module
|
|
142
|
+
const { transformedCode, imports } = transformModule(content);
|
|
143
|
+
|
|
144
|
+
// Load all import dependencies
|
|
145
|
+
const loadedDeps = await loadModuleDependencies(imports);
|
|
146
|
+
|
|
147
|
+
logger.debug(`Loaded ${loadedDeps.size} dependencies, executing transformed code...`);
|
|
148
|
+
|
|
149
|
+
// Create wrapped code with injected dependencies
|
|
150
|
+
const wrappedCode = wrapModuleCode(transformedCode, loadedDeps);
|
|
151
|
+
|
|
152
|
+
// Evaluate and get exports
|
|
153
|
+
moduleExports = evaluateModule(wrappedCode, loadedDeps);
|
|
154
|
+
|
|
155
|
+
logger.debug(`Module exports:`, Object.keys(moduleExports));
|
|
156
|
+
} else {
|
|
157
|
+
logger.debug(`Loading as CommonJS module: ${name}`);
|
|
158
|
+
|
|
159
|
+
// Wrap and evaluate as CommonJS
|
|
160
|
+
const wrappedCode = wrapCommonJSCode(content);
|
|
161
|
+
moduleExports = evaluateCommonJS(wrappedCode);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return moduleExports;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Load a JavaScript module in Node.js environment
|
|
169
|
+
*/
|
|
170
|
+
async function loadModuleInNode(path: string, name: string, moduleFileName?: string): Promise<any> {
|
|
171
|
+
if (moduleFileName) {
|
|
172
|
+
let s: string = dirname(moduleFileName);
|
|
173
|
+
if (s.startsWith('./')) {
|
|
174
|
+
s = s.substring(2);
|
|
175
|
+
} else if (s == '.') {
|
|
176
|
+
s = process.cwd();
|
|
177
|
+
}
|
|
178
|
+
path = `${s}${sep}${path}`;
|
|
179
|
+
}
|
|
180
|
+
if (!(path.startsWith(sep) || path.startsWith('.'))) {
|
|
181
|
+
path = process.cwd() + sep + path;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const m = await import(/* @vite-ignore */ path);
|
|
185
|
+
return m;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Usage: importModule("./mymodels/acme.js")
|
|
189
|
+
export async function importModule(path: string, name: string, moduleFileName?: string) {
|
|
190
|
+
if (importedModules.has(name)) {
|
|
191
|
+
logger.warn(`Alias '${name}' will overwrite a previously imported module`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let moduleExports: any;
|
|
195
|
+
|
|
196
|
+
if (isNodeEnv) {
|
|
197
|
+
moduleExports = await loadModuleInNode(path, name, moduleFileName);
|
|
198
|
+
} else {
|
|
199
|
+
moduleExports = await loadModuleInBrowser(path, name, moduleFileName);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
importedModules.set(name, moduleExports);
|
|
203
|
+
|
|
204
|
+
logger.info(`Successfully imported module: ${name}`, Object.keys(moduleExports));
|
|
205
|
+
|
|
206
|
+
return moduleExports;
|
|
54
207
|
}
|
|
55
208
|
|
|
56
209
|
export function moduleImported(moduleName: string): boolean {
|
|
57
210
|
return importedModules.has(moduleName);
|
|
58
211
|
}
|
|
59
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Get an imported module by its alias name
|
|
215
|
+
*/
|
|
216
|
+
export function getImportedModule(moduleName: string): any | undefined {
|
|
217
|
+
return importedModules.get(moduleName);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get all imported module names
|
|
222
|
+
*/
|
|
223
|
+
export function getImportedModuleNames(): string[] {
|
|
224
|
+
return Array.from(importedModules.keys());
|
|
225
|
+
}
|
|
226
|
+
|
|
60
227
|
function maybeEvalFunction(fnName: string): Function | undefined {
|
|
61
228
|
try {
|
|
62
229
|
return eval(fnName);
|
package/src/runtime/loader.ts
CHANGED
|
@@ -1143,9 +1143,10 @@ export async function internModule(
|
|
|
1143
1143
|
): Promise<Module> {
|
|
1144
1144
|
const mn = module.name;
|
|
1145
1145
|
const r = addModule(mn);
|
|
1146
|
-
|
|
1146
|
+
// Process imports sequentially to ensure all JS modules are loaded before definitions
|
|
1147
|
+
for (const imp of module.imports as Import[]) {
|
|
1147
1148
|
await importModule(imp.path, imp.name, moduleFileName);
|
|
1148
|
-
}
|
|
1149
|
+
}
|
|
1149
1150
|
for (let i = 0; i < module.defs.length; ++i) {
|
|
1150
1151
|
const def = module.defs[i];
|
|
1151
1152
|
await addFromDef(def, mn);
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ES6 Module Transformation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Transforms ES6 import/export syntax into code that can be evaluated
|
|
5
|
+
* in a browser environment without native ES6 module support.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { logger } from './logger.js';
|
|
9
|
+
|
|
10
|
+
export interface ImportInfo {
|
|
11
|
+
defaultImport?: string;
|
|
12
|
+
namedImports?: string[];
|
|
13
|
+
moduleSpecifier: string;
|
|
14
|
+
fullStatement: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface DynamicImportInfo {
|
|
18
|
+
fullMatch: string;
|
|
19
|
+
templateString: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TransformResult {
|
|
23
|
+
transformedCode: string;
|
|
24
|
+
imports: ImportInfo[];
|
|
25
|
+
dynamicImports: DynamicImportInfo[];
|
|
26
|
+
exports: string[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse ES6 import statements from code
|
|
31
|
+
* Matches: import ... from 'url'
|
|
32
|
+
*/
|
|
33
|
+
export function parseImports(content: string): ImportInfo[] {
|
|
34
|
+
const imports: ImportInfo[] = [];
|
|
35
|
+
|
|
36
|
+
// Match: import ... from 'url'
|
|
37
|
+
const importRegex = /import\s+(?:(\w+)|{([^}]+)})\s+from\s+['"]([^'"]+)['"]/g;
|
|
38
|
+
let match;
|
|
39
|
+
|
|
40
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
41
|
+
const [fullStatement, defaultImport, namedImports, moduleSpecifier] = match;
|
|
42
|
+
|
|
43
|
+
imports.push({
|
|
44
|
+
defaultImport,
|
|
45
|
+
namedImports: namedImports ? namedImports.split(',').map(n => n.trim()) : undefined,
|
|
46
|
+
moduleSpecifier,
|
|
47
|
+
fullStatement,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return imports;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse dynamic import statements
|
|
56
|
+
* Matches: await import(`${process.cwd()}/...`)
|
|
57
|
+
*/
|
|
58
|
+
export function parseDynamicImports(content: string): DynamicImportInfo[] {
|
|
59
|
+
const dynamicImports: DynamicImportInfo[] = [];
|
|
60
|
+
|
|
61
|
+
const dynamicImportRegex = /await\s+import\s*\(\s*`([^`]+)`\s*\)/g;
|
|
62
|
+
let match;
|
|
63
|
+
|
|
64
|
+
while ((match = dynamicImportRegex.exec(content)) !== null) {
|
|
65
|
+
const [fullMatch, templateString] = match;
|
|
66
|
+
dynamicImports.push({
|
|
67
|
+
fullMatch,
|
|
68
|
+
templateString,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return dynamicImports;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parse export statements and extract exported names
|
|
77
|
+
*/
|
|
78
|
+
export function parseExports(content: string): string[] {
|
|
79
|
+
const exportedNames: string[] = [];
|
|
80
|
+
|
|
81
|
+
// Handle: export function name() {}
|
|
82
|
+
const exportFnRegex = /export\s+(async\s+)?function\s+(\w+)/g;
|
|
83
|
+
let match;
|
|
84
|
+
|
|
85
|
+
while ((match = exportFnRegex.exec(content)) !== null) {
|
|
86
|
+
exportedNames.push(match[2]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle: export const name = ...
|
|
90
|
+
const exportConstRegex = /export\s+(const|let|var)\s+(\w+)/g;
|
|
91
|
+
|
|
92
|
+
while ((match = exportConstRegex.exec(content)) !== null) {
|
|
93
|
+
exportedNames.push(match[2]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle: export { name1, name2 }
|
|
97
|
+
const exportListRegex = /export\s*{\s*([^}]+)\s*}/g;
|
|
98
|
+
|
|
99
|
+
while ((match = exportListRegex.exec(content)) !== null) {
|
|
100
|
+
const names = match[1].split(',').map(n => n.trim().split(' as ')[0].trim());
|
|
101
|
+
exportedNames.push(...names);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return exportedNames;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Remove import statements from code
|
|
109
|
+
*/
|
|
110
|
+
export function removeImportStatements(content: string, imports: ImportInfo[]): string {
|
|
111
|
+
let result = content;
|
|
112
|
+
|
|
113
|
+
for (const imp of imports) {
|
|
114
|
+
result = result.replace(imp.fullStatement, '');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Remove export keywords from code
|
|
122
|
+
*/
|
|
123
|
+
export function removeExportKeywords(content: string): string {
|
|
124
|
+
let result = content;
|
|
125
|
+
|
|
126
|
+
// Remove: export function name() {}
|
|
127
|
+
result = result.replace(
|
|
128
|
+
/export\s+(async\s+)?function\s+(\w+)/g,
|
|
129
|
+
(match, async, name) => `${async || ''}function ${name}`
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Remove: export const name = ...
|
|
133
|
+
result = result.replace(
|
|
134
|
+
/export\s+(const|let|var)\s+(\w+)/g,
|
|
135
|
+
(match, keyword, name) => `${keyword} ${name}`
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Remove: export { name1, name2 }
|
|
139
|
+
result = result.replace(/export\s*{\s*[^}]+\s*}/g, '');
|
|
140
|
+
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Replace dynamic imports with variable references
|
|
146
|
+
*/
|
|
147
|
+
export function replaceDynamicImports(
|
|
148
|
+
content: string,
|
|
149
|
+
dynamicImports: DynamicImportInfo[]
|
|
150
|
+
): { code: string; varNames: Map<string, string> } {
|
|
151
|
+
let result = content;
|
|
152
|
+
const varNames = new Map<string, string>();
|
|
153
|
+
|
|
154
|
+
for (const dynImp of dynamicImports) {
|
|
155
|
+
// Clean up process.cwd() references
|
|
156
|
+
const cleanedPath = dynImp.templateString.replace(/\$\{process\.cwd\(\)\}/g, '');
|
|
157
|
+
|
|
158
|
+
// Create a variable name from the path
|
|
159
|
+
const varName = cleanedPath.split('/').pop()?.replace(/\.js$/, '') || 'dynamicModule';
|
|
160
|
+
|
|
161
|
+
varNames.set(cleanedPath, varName);
|
|
162
|
+
result = result.replace(dynImp.fullMatch, varName);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return { code: result, varNames };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Generate export assignments
|
|
170
|
+
*/
|
|
171
|
+
export function generateExportAssignments(exportedNames: string[]): string {
|
|
172
|
+
if (exportedNames.length === 0) {
|
|
173
|
+
return '';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const assignments = exportedNames.map(name => `exports.${name} = ${name};`).join('\n');
|
|
177
|
+
|
|
178
|
+
return `\n\n// Export assignments\n${assignments}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Transform ES6 module code to CommonJS-style code
|
|
183
|
+
*/
|
|
184
|
+
export function transformModule(content: string): TransformResult {
|
|
185
|
+
logger.debug('Transforming ES6 module code');
|
|
186
|
+
|
|
187
|
+
// Parse imports, exports, and dynamic imports
|
|
188
|
+
const imports = parseImports(content);
|
|
189
|
+
const dynamicImports = parseDynamicImports(content);
|
|
190
|
+
const exports = parseExports(content);
|
|
191
|
+
|
|
192
|
+
// Remove import statements
|
|
193
|
+
let transformedCode = removeImportStatements(content, imports);
|
|
194
|
+
|
|
195
|
+
// Handle dynamic imports
|
|
196
|
+
const { code: codeWithoutDynImports } = replaceDynamicImports(transformedCode, dynamicImports);
|
|
197
|
+
transformedCode = codeWithoutDynImports;
|
|
198
|
+
|
|
199
|
+
// Remove export keywords
|
|
200
|
+
transformedCode = removeExportKeywords(transformedCode);
|
|
201
|
+
|
|
202
|
+
// Add export assignments
|
|
203
|
+
transformedCode += generateExportAssignments(exports);
|
|
204
|
+
|
|
205
|
+
logger.debug(
|
|
206
|
+
`Found ${imports.length} imports, ${dynamicImports.length} dynamic imports, ${exports.length} exports`
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
transformedCode,
|
|
211
|
+
imports,
|
|
212
|
+
dynamicImports,
|
|
213
|
+
exports,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Create a wrapped function that evaluates the transformed code
|
|
219
|
+
* with injected dependencies
|
|
220
|
+
*/
|
|
221
|
+
export function wrapModuleCode(transformedCode: string, importedModules: Map<string, any>): string {
|
|
222
|
+
const importNames = Array.from(importedModules.keys());
|
|
223
|
+
|
|
224
|
+
const wrappedCode = `
|
|
225
|
+
(function(exports, ${importNames.join(', ')}) {
|
|
226
|
+
${transformedCode}
|
|
227
|
+
return exports;
|
|
228
|
+
})
|
|
229
|
+
`;
|
|
230
|
+
|
|
231
|
+
return wrappedCode;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Evaluate wrapped module code and return the exports
|
|
236
|
+
*/
|
|
237
|
+
export function evaluateModule(wrappedCode: string, importedModules: Map<string, any>): any {
|
|
238
|
+
const exportObj: any = {};
|
|
239
|
+
const importValues = Array.from(importedModules.values());
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const moduleFactory = eval(wrappedCode);
|
|
243
|
+
return moduleFactory(exportObj, ...importValues);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
logger.error('Failed to evaluate module:', error);
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Create CommonJS-style wrapper for code without ES6 imports
|
|
252
|
+
*/
|
|
253
|
+
export function wrapCommonJSCode(content: string): string {
|
|
254
|
+
return `
|
|
255
|
+
(function(module, exports) {
|
|
256
|
+
${content}
|
|
257
|
+
return module.exports || exports;
|
|
258
|
+
})
|
|
259
|
+
`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Evaluate CommonJS-style code
|
|
264
|
+
*/
|
|
265
|
+
export function evaluateCommonJS(wrappedCode: string): any {
|
|
266
|
+
const moduleObj: any = { exports: {} };
|
|
267
|
+
const exportsObj: any = {};
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
const moduleFactory = eval(wrappedCode);
|
|
271
|
+
const result = moduleFactory(moduleObj, exportsObj);
|
|
272
|
+
return result || moduleObj.exports || exportsObj;
|
|
273
|
+
} catch (error) {
|
|
274
|
+
logger.error('Failed to evaluate CommonJS module:', error);
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
parseAndEvaluateStatement,
|
|
16
16
|
} from '../interpreter.js';
|
|
17
17
|
import {
|
|
18
|
+
Agent,
|
|
18
19
|
asJSONSchema,
|
|
19
20
|
Decision,
|
|
20
21
|
fetchModule,
|
|
@@ -663,12 +664,25 @@ Only return a pure JSON object with no extra text, annotations etc.`;
|
|
|
663
664
|
if (entryName) {
|
|
664
665
|
const hasmod = slimModules.has(moduleName);
|
|
665
666
|
const defs = hasmod ? slimModules.get(moduleName) : new Array<string>();
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
667
|
+
// Try to get entry directly first, then try as an agent (agents have _agent suffix)
|
|
668
|
+
let entry = m.getEntrySafe(entryName);
|
|
669
|
+
if (!entry) {
|
|
670
|
+
// Try with agent suffix - agents are stored with escaped names
|
|
671
|
+
entry = m.getEntrySafe(Agent.EscapeName(entryName));
|
|
672
|
+
}
|
|
673
|
+
if (entry) {
|
|
674
|
+
const s =
|
|
675
|
+
entry instanceof Record ? (entry as Record).toString_(true) : entry.toString();
|
|
676
|
+
// Add full qualified name comment so LLM knows how to reference it
|
|
677
|
+
const fqName = `${moduleName}/${entryName}`;
|
|
678
|
+
defs?.push(
|
|
679
|
+
`# Tool: ${fqName}\n# Use as: {${fqName} {...}} or {${fqName}? {...}}\n${s}`
|
|
680
|
+
);
|
|
681
|
+
if (!hasmod && defs) {
|
|
682
|
+
slimModules.set(moduleName, defs);
|
|
683
|
+
}
|
|
684
|
+
} else {
|
|
685
|
+
logger.warn(`Tool entry '${entryName}' not found in module '${moduleName}'`);
|
|
672
686
|
}
|
|
673
687
|
} else {
|
|
674
688
|
tooldefs.push(fetchModule(moduleName).toString());
|
|
@@ -180,6 +180,19 @@ relationship RolePermission between(Role, Permission)
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
@public workflow GetPermissionsForRole {
|
|
184
|
+
{Role {__path__? GetPermissionsForRole.Role},
|
|
185
|
+
RolePermission {Permission? {}},
|
|
186
|
+
@into
|
|
187
|
+
{Id Permission.id,
|
|
188
|
+
resourceFqName Permission.resourceFqName,
|
|
189
|
+
c Permission.c,
|
|
190
|
+
r Permission.r,
|
|
191
|
+
u Permission.u,
|
|
192
|
+
d Permission.d}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
183
196
|
@public workflow AssignUserToRole {
|
|
184
197
|
{User {id? AssignUserToRole.userId}} @as [user];
|
|
185
198
|
{Role {name? AssignUserToRole.roleName}} @as [role];
|
|
@@ -1358,7 +1371,7 @@ export async function getUserInfo(
|
|
|
1358
1371
|
}
|
|
1359
1372
|
if (role) {
|
|
1360
1373
|
permissions = await evalEvent(
|
|
1361
|
-
'
|
|
1374
|
+
'GetPermissionsForRole',
|
|
1362
1375
|
{
|
|
1363
1376
|
Role: role,
|
|
1364
1377
|
},
|
|
@@ -1408,7 +1421,7 @@ export async function getUserInfoByEmail(
|
|
|
1408
1421
|
}
|
|
1409
1422
|
if (role) {
|
|
1410
1423
|
permissions = await evalEvent(
|
|
1411
|
-
'
|
|
1424
|
+
'GetPermissionsForRole',
|
|
1412
1425
|
{
|
|
1413
1426
|
Role: role,
|
|
1414
1427
|
},
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
escapeSpecialChars,
|
|
8
8
|
isString,
|
|
9
9
|
restoreSpecialChars,
|
|
10
|
+
makeCoreModuleName,
|
|
10
11
|
} from '../util.js';
|
|
11
12
|
import { Instance, isInstanceOfType, makeInstance, newInstanceAttributes } from '../module.js';
|
|
12
13
|
import {
|
|
@@ -139,9 +140,18 @@ export const CoreModules: string[] = [];
|
|
|
139
140
|
export function registerCoreModules() {
|
|
140
141
|
DefaultModules.add(DefaultModuleName);
|
|
141
142
|
CoreModules.push(CoreModuleDefinition);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
|
|
144
|
+
// Map of module definitions to their names for proper DefaultModules registration
|
|
145
|
+
const coreModuleInfo: Array<{ def: string; name: string }> = [
|
|
146
|
+
{ def: auth, name: makeCoreModuleName('auth') },
|
|
147
|
+
{ def: ai, name: makeCoreModuleName('ai') },
|
|
148
|
+
{ def: files, name: makeCoreModuleName('files') },
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
coreModuleInfo.forEach(({ def, name }) => {
|
|
152
|
+
CoreModules.push(def);
|
|
153
|
+
// Add module NAME (not definition) to DefaultModules so flushAllModules() doesn't remove core modules
|
|
154
|
+
DefaultModules.add(name);
|
|
145
155
|
});
|
|
146
156
|
}
|
|
147
157
|
|