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.
Files changed (48) hide show
  1. package/out/language/generated/ast.js +1 -0
  2. package/out/language/generated/ast.js.map +1 -1
  3. package/out/language/main.cjs.map +1 -1
  4. package/out/runtime/defs.d.ts +9 -0
  5. package/out/runtime/defs.d.ts.map +1 -1
  6. package/out/runtime/defs.js +7 -0
  7. package/out/runtime/defs.js.map +1 -1
  8. package/out/runtime/jsmodules.d.ts +8 -0
  9. package/out/runtime/jsmodules.d.ts.map +1 -1
  10. package/out/runtime/jsmodules.js +139 -22
  11. package/out/runtime/jsmodules.js.map +1 -1
  12. package/out/runtime/loader.d.ts.map +1 -1
  13. package/out/runtime/loader.js +3 -2
  14. package/out/runtime/loader.js.map +1 -1
  15. package/out/runtime/module-transform.d.ts +77 -0
  16. package/out/runtime/module-transform.d.ts.map +1 -0
  17. package/out/runtime/module-transform.js +201 -0
  18. package/out/runtime/module-transform.js.map +1 -0
  19. package/out/runtime/modules/ai.d.ts.map +1 -1
  20. package/out/runtime/modules/ai.js +18 -6
  21. package/out/runtime/modules/ai.js.map +1 -1
  22. package/out/runtime/modules/auth.d.ts.map +1 -1
  23. package/out/runtime/modules/auth.js +15 -2
  24. package/out/runtime/modules/auth.js.map +1 -1
  25. package/out/runtime/modules/core.d.ts.map +1 -1
  26. package/out/runtime/modules/core.js +11 -4
  27. package/out/runtime/modules/core.js.map +1 -1
  28. package/package.json +185 -186
  29. package/src/language/generated/ast.ts +1 -1
  30. package/src/runtime/defs.ts +20 -0
  31. package/src/runtime/jsmodules.ts +189 -22
  32. package/src/runtime/loader.ts +3 -2
  33. package/src/runtime/module-transform.ts +277 -0
  34. package/src/runtime/modules/ai.ts +20 -6
  35. package/src/runtime/modules/auth.ts +15 -2
  36. package/src/runtime/modules/core.ts +13 -3
  37. package/out/setupClassic.d.ts +0 -98
  38. package/out/setupClassic.d.ts.map +0 -1
  39. package/out/setupClassic.js +0 -38
  40. package/out/setupClassic.js.map +0 -1
  41. package/out/setupCommon.d.ts +0 -2
  42. package/out/setupCommon.d.ts.map +0 -1
  43. package/out/setupCommon.js +0 -33
  44. package/out/setupCommon.js.map +0 -1
  45. package/out/setupExtended.d.ts +0 -40
  46. package/out/setupExtended.d.ts.map +0 -1
  47. package/out/setupExtended.js +0 -67
  48. package/out/setupExtended.js.map +0 -1
@@ -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
- // Usage: importModule("./mymodels/acme.js")
28
- export async function importModule(path: string, name: string, moduleFileName?: string) {
29
- if (isNodeEnv) {
30
- if (importedModules.has(name)) {
31
- logger.warn(`Alias '${name}' will overwrite a previously imported module`);
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
- if (moduleFileName) {
34
- let s: string = dirname(moduleFileName);
35
- if (s.startsWith('./')) {
36
- s = s.substring(2);
37
- } else if (s == '.') {
38
- s = process.cwd();
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
- path = `${s}${sep}${path}`;
70
+ } else {
71
+ logger.debug(`Using pre-imported dependency: ${moduleSpecifier}`);
41
72
  }
42
- if (!(path.startsWith(sep) || path.startsWith('.'))) {
43
- path = process.cwd() + sep + path;
73
+
74
+ // Handle default import
75
+ if (imp.defaultImport) {
76
+ loadedDeps.set(imp.defaultImport, module.default || module);
44
77
  }
45
- const m = await import(/* @vite-ignore */ path);
46
- importedModules.set(name, m);
47
- // e.g of dynamic fn-call:
48
- //// let f = eval("(a, b) => m.add(a, b)");
49
- //// console.log(f(10, 20))
50
- return m;
51
- } else {
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);
@@ -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
- module.imports.forEach(async (imp: Import) => {
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
- const entry = m.getEntry(entryName);
667
- const s =
668
- entry instanceof Record ? (entry as Record).toString_(true) : entry.toString();
669
- defs?.push(s);
670
- if (!hasmod && defs) {
671
- slimModules.set(moduleName, defs);
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
- 'ListRolePermissions',
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
- 'ListRolePermissions',
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
- [auth, ai, files].forEach((mdef: string) => {
143
- CoreModules.push(mdef);
144
- DefaultModules.add(mdef);
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