@smythos/sre 1.5.26 → 1.5.31

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.
@@ -9,6 +9,8 @@ import { AWSConfig, AWSCredentials, AWSRegionConfig } from '@sre/types/AWS.types
9
9
  import { VaultHelper } from '@sre/Security/Vault.service/Vault.helper';
10
10
  import { IAgent } from '@sre/types/Agent.types';
11
11
  import { SystemEvents } from '@sre/Core/SystemEvents';
12
+ import * as acorn from 'acorn';
13
+
12
14
  export const cachePrefix = 'serverless_code';
13
15
  export const cacheTTL = 60 * 60 * 24 * 16; // 16 days
14
16
  const PER_SECOND_COST = 0.0001;
@@ -18,11 +20,10 @@ export function getLambdaFunctionName(agentId: string, componentId: string) {
18
20
  }
19
21
 
20
22
 
21
- export function generateCodeHash(code_body: string, code_imports: string, codeInputs: string[]) {
22
- const importsHash = getSanitizeCodeHash(code_imports);
23
+ export function generateCodeHash(code_body: string, codeInputs: string[]) {
23
24
  const bodyHash = getSanitizeCodeHash(code_body);
24
25
  const inputsHash = getSanitizeCodeHash(JSON.stringify(codeInputs));
25
- return `imports-${importsHash}__body-${bodyHash}__inputs-${inputsHash}`;
26
+ return `body-${bodyHash}__inputs-${inputsHash}`;
26
27
  }
27
28
 
28
29
  export function getSanitizeCodeHash(code: string) {
@@ -81,49 +82,17 @@ export async function setDeployedCodeHash(agentId: string, componentId: string,
81
82
  .set(`${cachePrefix}_${agentId}-${componentId}`, codeHash, null, null, cacheTTL);
82
83
  }
83
84
 
84
-
85
- export function extractNpmImports(code: string) {
86
- const importRegex = /import\s+(?:[\w*\s{},]*\s+from\s+)?['"]([^'"]+)['"]/g;
87
- const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
88
- const dynamicImportRegex = /import\(['"]([^'"]+)['"]\)/g;
89
-
90
- let libraries = new Set();
91
- let match;
92
-
93
- // Function to extract the main package name
94
- function extractPackageName(modulePath: string) {
95
- if (modulePath.startsWith('@')) {
96
- // Handle scoped packages (e.g., @babel/core)
97
- return modulePath.split('/').slice(0, 2).join('/');
98
- }
99
- return modulePath.split('/')[0]; // Extract the first part (main package)
100
- }
101
- // Match static ESM imports
102
- while ((match = importRegex.exec(code)) !== null) {
103
- libraries.add(extractPackageName(match[1]));
104
- }
105
- // Match CommonJS require() calls
106
- while ((match = requireRegex.exec(code)) !== null) {
107
- libraries.add(extractPackageName(match[1]));
108
- }
109
- // Match dynamic import() calls
110
- while ((match = dynamicImportRegex.exec(code)) !== null) {
111
- libraries.add(extractPackageName(match[1]));
112
- }
113
-
114
- return Array.from(libraries);
115
- }
116
-
117
-
118
- export function generateLambdaCode(code_imports: string, code_body: string, input_variables: string[]) {
119
- const lambdaCode = `${code_imports}\nexport const handler = async (event, context) => {
85
+ export function generateLambdaCode(code: string, parameters: string[]) {
86
+ const lambdaCode = `
87
+ ${code}
88
+ export const handler = async (event, context) => {
120
89
  try {
121
90
  context.callbackWaitsForEmptyEventLoop = false;
122
91
  let startTime = Date.now();
123
- const result = await (async () => {
124
- ${input_variables && input_variables.length ? input_variables.map((variable) => `const ${variable} = event.${variable};`).join('\n') : ''}
125
- ${code_body}
126
- })();
92
+
93
+ ${parameters && parameters.length ? parameters.map((variable) => `const ${variable} = event.${variable};`).join('\n') : ''}
94
+ const result = await main(${parameters.join(', ')});
95
+
127
96
  let endTime = Date.now();
128
97
  return {
129
98
  result,
@@ -385,4 +354,175 @@ export function reportUsage({ cost, agentId, teamId }: { cost: number; agentId:
385
354
  agentId,
386
355
  teamId,
387
356
  });
388
- }
357
+ }
358
+
359
+ export function validateAsyncMainFunction(code: string): { isValid: boolean; error?: string; parameters?: string[]; dependencies?: string[] } {
360
+ try {
361
+ // Parse the code using acorn
362
+ const ast = acorn.parse(code, {
363
+ ecmaVersion: 'latest',
364
+ sourceType: 'module'
365
+ });
366
+
367
+ // Extract library imports
368
+ const libraries = new Set<string>();
369
+ function extractPackageName(modulePath: string): string {
370
+ if (modulePath.startsWith('@')) {
371
+ // Handle scoped packages (e.g., @babel/core)
372
+ return modulePath.split('/').slice(0, 2).join('/');
373
+ }
374
+ return modulePath.split('/')[0]; // Extract the first part (main package)
375
+ }
376
+
377
+ function processNodeForImports(node: any): void {
378
+ if (!node) return;
379
+
380
+ // Handle ImportDeclaration (ES6 imports)
381
+ if (node.type === 'ImportDeclaration') {
382
+ const modulePath = node.source.value;
383
+ if (modulePath && !modulePath.startsWith('.') && !modulePath.startsWith('/')) {
384
+ // Skip relative imports and absolute paths
385
+ libraries.add(extractPackageName(modulePath));
386
+ }
387
+ }
388
+
389
+ // Handle CallExpression (require() calls)
390
+ if (node.type === 'CallExpression' &&
391
+ node.callee.type === 'Identifier' &&
392
+ node.callee.name === 'require' &&
393
+ node.arguments.length > 0 &&
394
+ node.arguments[0].type === 'Literal') {
395
+ const modulePath = node.arguments[0].value;
396
+ if (modulePath && !modulePath.startsWith('.') && !modulePath.startsWith('/')) {
397
+ libraries.add(extractPackageName(modulePath));
398
+ }
399
+ }
400
+
401
+ // Handle dynamic import() calls
402
+ if (node.type === 'CallExpression' &&
403
+ node.callee.type === 'Import' &&
404
+ node.arguments.length > 0 &&
405
+ node.arguments[0].type === 'Literal') {
406
+ const modulePath = node.arguments[0].value;
407
+ if (modulePath && !modulePath.startsWith('.') && !modulePath.startsWith('/')) {
408
+ libraries.add(extractPackageName(modulePath));
409
+ }
410
+ }
411
+
412
+ // Recursively process child nodes
413
+ for (const key in node) {
414
+ if (node[key] && typeof node[key] === 'object') {
415
+ if (Array.isArray(node[key])) {
416
+ (node[key] as any[]).forEach(processNodeForImports);
417
+ } else {
418
+ processNodeForImports(node[key]);
419
+ }
420
+ }
421
+ }
422
+ }
423
+
424
+ // Extract dependencies from the entire AST
425
+ processNodeForImports(ast);
426
+ const dependencies = Array.from(libraries) as string[];
427
+
428
+ // Check if there's a function declaration or function expression named 'main' at the root level
429
+ let hasAsyncMain = false;
430
+ let hasMain = false;
431
+ let mainParameters: string[] = [];
432
+
433
+ for (const node of ast.body) {
434
+ if (node.type === 'FunctionDeclaration') {
435
+ if (node.id?.name === 'main') {
436
+ hasMain = true;
437
+ if (node.async) {
438
+ hasAsyncMain = true;
439
+ mainParameters = extractParameters(node.params);
440
+ break;
441
+ }
442
+ }
443
+ } else if (node.type === 'VariableDeclaration') {
444
+ // Check for const/let/var main = async function() or const/let/var main = async () =>
445
+ for (const declarator of node.declarations) {
446
+ if (declarator.id.type === 'Identifier' && declarator.id.name === 'main') {
447
+ hasMain = true;
448
+ if (declarator.init) {
449
+ if (declarator.init.type === 'FunctionExpression' && declarator.init.async) {
450
+ hasAsyncMain = true;
451
+ mainParameters = extractParameters(declarator.init.params);
452
+ break;
453
+ } else if (declarator.init.type === 'ArrowFunctionExpression' && declarator.init.async) {
454
+ hasAsyncMain = true;
455
+ mainParameters = extractParameters(declarator.init.params);
456
+ break;
457
+ }
458
+ }
459
+ }
460
+ }
461
+ } else if (node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression') {
462
+ // Check for main = async function() or main = async () =>
463
+ if (node.expression.left.type === 'Identifier' && node.expression.left.name === 'main') {
464
+ hasMain = true;
465
+ const right = node.expression.right;
466
+ if ((right.type === 'FunctionExpression' || right.type === 'ArrowFunctionExpression') && right.async) {
467
+ hasAsyncMain = true;
468
+ mainParameters = extractParameters(right.params);
469
+ break;
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ if (!hasMain) {
476
+ return {
477
+ isValid: false,
478
+ error: 'No main function found at root level',
479
+ dependencies
480
+ };
481
+ }
482
+
483
+ if (!hasAsyncMain) {
484
+ return {
485
+ isValid: false,
486
+ error: 'Main function exists but is not async',
487
+ dependencies
488
+ };
489
+ }
490
+
491
+ return { isValid: true, parameters: mainParameters, dependencies };
492
+ } catch (error) {
493
+ return {
494
+ isValid: false,
495
+ error: `Failed to parse code: ${error.message}`
496
+ };
497
+ }
498
+ }
499
+
500
+ function extractParameters(params: any[]): string[] {
501
+ return params.map((param: any): string => {
502
+ if (param.type === 'Identifier') {
503
+ return param.name;
504
+ } else if (param.type === 'AssignmentPattern' && param.left.type === 'Identifier') {
505
+ return param.left.name;
506
+ } else if (param.type === 'RestElement' && param.argument.type === 'Identifier') {
507
+ return param.argument.name;
508
+ } else if (param.type === 'ObjectPattern') {
509
+ // For destructured objects, return the object name or a placeholder
510
+ return param.name || '[object]';
511
+ } else if (param.type === 'ArrayPattern') {
512
+ // For destructured arrays, return a placeholder
513
+ return '[array]';
514
+ }
515
+ return '[unknown]';
516
+ });
517
+ }
518
+
519
+ export function generateCodeFromLegacyComponent(code_body: string, code_imports: string, codeInputs: string[]) {
520
+ const code = `
521
+ ${code_imports}
522
+ async function main(${codeInputs.join(', ')}) {
523
+ ${code_body}
524
+ }
525
+ `
526
+ return code;
527
+ }
528
+
@@ -1075,7 +1075,7 @@ export class Conversation extends EventEmitter {
1075
1075
 
1076
1076
  if (param.type === 'ObjectPattern') {
1077
1077
  // For destructured objects, output as a single parameter with nested fields
1078
- const name = `[object_${counter++}]`;
1078
+ const name = `object___${counter++}`;
1079
1079
  return {
1080
1080
  name,
1081
1081
  in: 'query',
@@ -1094,7 +1094,7 @@ export class Conversation extends EventEmitter {
1094
1094
  };
1095
1095
  }
1096
1096
 
1097
- const name = `[unknown_${counter++}]`;
1097
+ const name = `unknown___${counter++}`;
1098
1098
  return {
1099
1099
  name,
1100
1100
  in: 'query',