@output.ai/core 0.3.0-dev.pr263-8f8e94a → 0.3.0-dev.pr263-5d2eaa9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@output.ai/core",
3
- "version": "0.3.0-dev.pr263-8f8e94a",
3
+ "version": "0.3.0-dev.pr263-5d2eaa9",
4
4
  "description": "The core module of the output framework",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,7 +1,7 @@
1
1
  import traverseModule from '@babel/traverse';
2
2
  import { dirname } from 'node:path';
3
3
  import { parse, toAbsolutePath, getFileKind, isAnyStepsPath, isEvaluatorsPath, isWorkflowPath } from '../tools.js';
4
- import { ComponentFile, CoreModule } from '../consts.js';
4
+ import { ComponentFile } from '../consts.js';
5
5
  import {
6
6
  isCallExpression,
7
7
  isFunctionExpression,
@@ -36,57 +36,6 @@ const getFileKindLabel = filename => {
36
36
  return filename;
37
37
  };
38
38
 
39
- /**
40
- * Check if workflow dependencies are valid.
41
- * Workflows can import:
42
- * - Components (steps, evaluators, workflow)
43
- * - Core modules (@output.ai/core, local_core)
44
- * - ANY file that is NOT a component file (flexible utility imports)
45
- */
46
- const validateWorkflowImports = ( { specifier, filename } ) => {
47
- const isCore = Object.values( CoreModule ).includes( specifier );
48
- const fileKind = getFileKind( specifier );
49
- const isComponent = Object.values( ComponentFile ).includes( fileKind );
50
- const isNonComponentFile = fileKind === null;
51
-
52
- if ( !isCore && !isComponent && !isNonComponentFile ) {
53
- throw new Error( `Invalid dependency in workflow.js: '${specifier}'. \
54
- Only components (${Object.values( ComponentFile ) } ), @output.ai/core, or non-component files are allowed in ${filename}` );
55
- }
56
- };
57
-
58
- /**
59
- * Check if evaluators or steps import invalid dependencies.
60
- * Steps and evaluators CANNOT import:
61
- * - Other steps (local or shared) - activity isolation
62
- * - Other evaluators (local or shared) - activity isolation
63
- * - Workflows
64
- *
65
- * Steps and evaluators CAN import:
66
- * - ANY file that is NOT a component file (flexible utility imports)
67
- */
68
- const validateStepEvaluatorImports = ( { specifier, filename } ) => {
69
- const importedFileKind = getFileKind( specifier );
70
-
71
- // Activity isolation: steps/evaluators cannot import other steps, evaluators, or workflows
72
- if ( Object.values( ComponentFile ).includes( importedFileKind ) ) {
73
- const fileLabel = getFileKindLabel( filename );
74
- throw new Error( `Invalid dependency in ${fileLabel}: '${specifier}'. \
75
- Steps, evaluators or workflows are not allowed dependencies in ${filename}` );
76
- }
77
- };
78
-
79
- /**
80
- * Validate import for evaluators, steps, workflow
81
- */
82
- const executeImportValidations = ( { fileKind, specifier, filename } ) => {
83
- if ( fileKind === ComponentFile.WORKFLOW ) {
84
- validateWorkflowImports( { specifier, filename } );
85
- } else if ( Object.values( ComponentFile ).includes( fileKind ) ) {
86
- validateStepEvaluatorImports( { specifier, filename } );
87
- }
88
- };
89
-
90
39
  /**
91
40
  * Validate that component instantiation calls occur in the correct file locations.
92
41
  * - step() must be called in a file whose path contains 'steps'
@@ -108,17 +57,15 @@ const validateInstantiationLocation = ( calleeName, filename ) => {
108
57
  };
109
58
 
110
59
  /**
111
- * Webpack loader that validates imports and disallowed calls across modules.
60
+ * Webpack loader that validates component instantiation and fn body calls.
112
61
  * Returns the source unchanged unless a validation error is found.
113
62
  *
114
63
  * Rules enforced:
115
64
  * - Instantiation location: step() must be in steps path, evaluator() in evaluators path, workflow() in workflow path
116
- * - evaluators.js `fn`: at each evaluator().fn body: calling any evaluator, step, or workflow is forbidden
117
- * - evaluators.js: may not import evaluators.js, steps.js, workflow.js, or any shared steps/evaluators
118
- * - steps.js: at each step().fn body: calling any evaluator, step, or workflow is forbidden
119
- * - steps.js: may not import evaluators.js, steps.js, workflow.js, or any shared steps/evaluators
120
- * - workflow.js: may import components (evaluators.js, steps.js, workflow.js including shared);
121
- * and any non-component file, or `@output.ai/core`
65
+ * - steps.js `fn`: calling any step, evaluator, or workflow inside fn body emits warning
66
+ * - evaluators.js `fn`: calling any step, evaluator, or workflow inside fn body emits warning
67
+ *
68
+ * NOTE: Import restrictions have been removed - any file can import any other file.
122
69
  *
123
70
  * @param {string|Buffer} source
124
71
  * @param {any} inputMap
@@ -127,6 +74,7 @@ const validateInstantiationLocation = ( calleeName, filename ) => {
127
74
  export default function workflowValidatorLoader( source, inputMap ) {
128
75
  this.cacheable?.( true );
129
76
  const callback = this.async?.() ?? this.callback;
77
+ const emitWarning = this.emitWarning?.bind( this ) ?? ( () => {} );
130
78
 
131
79
  try {
132
80
  const filename = this.resourcePath;
@@ -142,13 +90,11 @@ export default function workflowValidatorLoader( source, inputMap ) {
142
90
  const importedEvaluatorIds = new Set();
143
91
  const importedWorkflowIds = new Set();
144
92
 
145
- // First pass: module-level import validation + collect imported ids
93
+ // First pass: collect imported identifiers for fn body call checks
146
94
  traverse( ast, {
147
95
  ImportDeclaration: path => {
148
96
  const specifier = path.node.source.value;
149
97
 
150
- executeImportValidations( { fileKind, specifier, filename } );
151
-
152
98
  // Collect imported identifiers for later call checks
153
99
  const importedKind = getFileKind( specifier );
154
100
  const accumulator = ( {
@@ -187,35 +133,32 @@ export default function workflowValidatorLoader( source, inputMap ) {
187
133
  validateInstantiationLocation( 'workflow', filename );
188
134
  }
189
135
 
190
- // CommonJS requires: validate source and collect identifiers
136
+ // CommonJS requires: collect identifiers for fn body call checks
191
137
  if ( isIdentifier( init.callee, { name: 'require' } ) ) {
192
138
  const firstArg = init.arguments[0];
193
139
  if ( !isStringLiteral( firstArg ) ) {
194
140
  return;
195
141
  }
196
142
  const req = firstArg.value;
197
- executeImportValidations( { fileKind, specifier: req, filename } );
198
143
 
199
144
  // Collect imported identifiers from require patterns
200
- if ( isStringLiteral( firstArg ) ) {
201
- const reqType = getFileKind( toAbsolutePath( fileDir, req ) );
202
- if ( reqType === ComponentFile.STEPS && isObjectPattern( path.node.id ) ) {
203
- for ( const prop of path.node.id.properties ) {
204
- if ( isObjectProperty( prop ) && isIdentifier( prop.value ) ) {
205
- importedStepIds.add( prop.value.name );
206
- }
145
+ const reqType = getFileKind( toAbsolutePath( fileDir, req ) );
146
+ if ( reqType === ComponentFile.STEPS && isObjectPattern( path.node.id ) ) {
147
+ for ( const prop of path.node.id.properties ) {
148
+ if ( isObjectProperty( prop ) && isIdentifier( prop.value ) ) {
149
+ importedStepIds.add( prop.value.name );
207
150
  }
208
151
  }
209
- if ( reqType === ComponentFile.EVALUATORS && isObjectPattern( path.node.id ) ) {
210
- for ( const prop of path.node.id.properties ) {
211
- if ( isObjectProperty( prop ) && isIdentifier( prop.value ) ) {
212
- importedEvaluatorIds.add( prop.value.name );
213
- }
152
+ }
153
+ if ( reqType === ComponentFile.EVALUATORS && isObjectPattern( path.node.id ) ) {
154
+ for ( const prop of path.node.id.properties ) {
155
+ if ( isObjectProperty( prop ) && isIdentifier( prop.value ) ) {
156
+ importedEvaluatorIds.add( prop.value.name );
214
157
  }
215
158
  }
216
- if ( reqType === ComponentFile.WORKFLOW && isIdentifier( path.node.id ) ) {
217
- importedWorkflowIds.add( path.node.id.name );
218
- }
159
+ }
160
+ if ( reqType === ComponentFile.WORKFLOW && isIdentifier( path.node.id ) ) {
161
+ importedWorkflowIds.add( path.node.id.name );
219
162
  }
220
163
  }
221
164
  }
@@ -246,7 +189,7 @@ export default function workflowValidatorLoader( source, inputMap ) {
246
189
  ].find( v => v[1] )?.[0];
247
190
 
248
191
  if ( violation ) {
249
- throw new Error( `Invalid call in ${fileLabel} fn: calling a ${violation} ('${name}') is not allowed in ${filename}` );
192
+ emitWarning( new Error( `Invalid call in ${fileLabel} fn: calling a ${violation} ('${name}') is not allowed in ${filename}` ) );
250
193
  }
251
194
  }
252
195
  }
@@ -6,11 +6,13 @@ import validatorLoader from './index.mjs';
6
6
 
7
7
  function runLoader( filename, source ) {
8
8
  return new Promise( ( resolve, reject ) => {
9
+ const warnings = [];
9
10
  const ctx = {
10
11
  resourcePath: filename,
11
12
  cacheable: () => {},
12
- async: () => ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map } ) ),
13
- callback: ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map } ) )
13
+ emitWarning: err => warnings.push( err ),
14
+ async: () => ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map, warnings } ) ),
15
+ callback: ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map, warnings } ) )
14
16
  };
15
17
  validatorLoader.call( ctx, source, null );
16
18
  } );
@@ -52,10 +54,11 @@ describe( 'workflow_validator loader', () => {
52
54
  rmSync( dir, { recursive: true, force: true } );
53
55
  } );
54
56
 
55
- it( 'steps.js: rejects importing steps/evaluators/workflow', async () => {
56
- const dir = mkdtempSync( join( tmpdir(), 'steps-reject-' ) );
57
+ it( 'steps.js: allows importing steps/evaluators/workflow (no import restrictions)', async () => {
58
+ const dir = mkdtempSync( join( tmpdir(), 'steps-allow-import-' ) );
57
59
  const src = 'import { S } from "./steps.js";';
58
- await expect( runLoader( join( dir, 'steps.js' ), src ) ).rejects.toThrow( /Invalid (import|imports|dependency) in steps\.js/ );
60
+ const result = await runLoader( join( dir, 'steps.js' ), src );
61
+ expect( result.warnings ).toHaveLength( 0 );
59
62
  rmSync( dir, { recursive: true, force: true } );
60
63
  } );
61
64
 
@@ -66,14 +69,15 @@ describe( 'workflow_validator loader', () => {
66
69
  rmSync( dir, { recursive: true, force: true } );
67
70
  } );
68
71
 
69
- it( 'evaluators.js: rejects importing evaluators/steps/workflow', async () => {
70
- const dir = mkdtempSync( join( tmpdir(), 'evals-reject-' ) );
72
+ it( 'evaluators.js: allows importing evaluators/steps/workflow (no import restrictions)', async () => {
73
+ const dir = mkdtempSync( join( tmpdir(), 'evals-allow-import-' ) );
71
74
  const src = 'import { E } from "./evaluators.js";';
72
- await expect( runLoader( join( dir, 'evaluators.js' ), src ) ).rejects.toThrow( /Invalid (import|imports|dependency) in evaluators\.js/ );
75
+ const result = await runLoader( join( dir, 'evaluators.js' ), src );
76
+ expect( result.warnings ).toHaveLength( 0 );
73
77
  rmSync( dir, { recursive: true, force: true } );
74
78
  } );
75
79
 
76
- it( 'steps.js: rejects calling another step inside fn', async () => {
80
+ it( 'steps.js: warns when calling another step inside fn', async () => {
77
81
  const dir = mkdtempSync( join( tmpdir(), 'steps-call-reject-' ) );
78
82
  // Can only test same-type components since cross-type declarations are now blocked by instantiation validation
79
83
  const src = [
@@ -81,11 +85,13 @@ describe( 'workflow_validator loader', () => {
81
85
  'const B = step({ name: "b" });',
82
86
  'const obj = { fn: function() { B(); } };'
83
87
  ].join( '\n' );
84
- await expect( runLoader( join( dir, 'steps.js' ), src ) ).rejects.toThrow( /Invalid call in .*\.js fn/ );
88
+ const result = await runLoader( join( dir, 'steps.js' ), src );
89
+ expect( result.warnings ).toHaveLength( 1 );
90
+ expect( result.warnings[0].message ).toMatch( /Invalid call in .*\.js fn/ );
85
91
  rmSync( dir, { recursive: true, force: true } );
86
92
  } );
87
93
 
88
- it( 'evaluators.js: rejects calling another evaluator inside fn', async () => {
94
+ it( 'evaluators.js: warns when calling another evaluator inside fn', async () => {
89
95
  const dir = mkdtempSync( join( tmpdir(), 'evals-call-reject-' ) );
90
96
  // Can only test same-type components since cross-type declarations are now blocked by instantiation validation
91
97
  const src = [
@@ -93,7 +99,9 @@ describe( 'workflow_validator loader', () => {
93
99
  'const E2 = evaluator({ name: "e2" });',
94
100
  'const obj = { fn: function() { E2(); } };'
95
101
  ].join( '\n' );
96
- await expect( runLoader( join( dir, 'evaluators.js' ), src ) ).rejects.toThrow( /Invalid call in .*\.js fn/ );
102
+ const result = await runLoader( join( dir, 'evaluators.js' ), src );
103
+ expect( result.warnings ).toHaveLength( 1 );
104
+ expect( result.warnings[0].message ).toMatch( /Invalid call in .*\.js fn/ );
97
105
  rmSync( dir, { recursive: true, force: true } );
98
106
  } );
99
107
 
@@ -130,21 +138,21 @@ describe( 'workflow_validator loader', () => {
130
138
  rmSync( dir, { recursive: true, force: true } );
131
139
  } );
132
140
 
133
- it( 'steps.js: rejects importing evaluators/workflow variants', async () => {
134
- const dir = mkdtempSync( join( tmpdir(), 'steps-reject2-' ) );
135
- await expect( runLoader( join( dir, 'steps.js' ), 'import { E } from "./evaluators.js";' ) )
136
- .rejects.toThrow( /Invalid (import|imports|dependency) in steps\.js/ );
137
- await expect( runLoader( join( dir, 'steps.js' ), 'import WF from "./workflow.js";' ) )
138
- .rejects.toThrow( /Invalid (import|imports|dependency) in steps\.js/ );
141
+ it( 'steps.js: allows importing evaluators/workflow variants (no import restrictions)', async () => {
142
+ const dir = mkdtempSync( join( tmpdir(), 'steps-allow-import2-' ) );
143
+ const result1 = await runLoader( join( dir, 'steps.js' ), 'import { E } from "./evaluators.js";' );
144
+ expect( result1.warnings ).toHaveLength( 0 );
145
+ const result2 = await runLoader( join( dir, 'steps.js' ), 'import WF from "./workflow.js";' );
146
+ expect( result2.warnings ).toHaveLength( 0 );
139
147
  rmSync( dir, { recursive: true, force: true } );
140
148
  } );
141
149
 
142
- it( 'evaluators.js: rejects importing steps/workflow variants', async () => {
143
- const dir = mkdtempSync( join( tmpdir(), 'evals-reject2-' ) );
144
- await expect( runLoader( join( dir, 'evaluators.js' ), 'import { S } from "./steps.js";' ) )
145
- .rejects.toThrow( /Invalid (import|imports|dependency) in evaluators\.js/ );
146
- await expect( runLoader( join( dir, 'evaluators.js' ), 'import WF from "./workflow.js";' ) )
147
- .rejects.toThrow( /Invalid (import|imports|dependency) in evaluators\.js/ );
150
+ it( 'evaluators.js: allows importing steps/workflow variants (no import restrictions)', async () => {
151
+ const dir = mkdtempSync( join( tmpdir(), 'evals-allow-import2-' ) );
152
+ const result1 = await runLoader( join( dir, 'evaluators.js' ), 'import { S } from "./steps.js";' );
153
+ expect( result1.warnings ).toHaveLength( 0 );
154
+ const result2 = await runLoader( join( dir, 'evaluators.js' ), 'import WF from "./workflow.js";' );
155
+ expect( result2.warnings ).toHaveLength( 0 );
148
156
  rmSync( dir, { recursive: true, force: true } );
149
157
  } );
150
158
 
@@ -176,27 +184,29 @@ describe( 'workflow_validator loader', () => {
176
184
  rmSync( dir, { recursive: true, force: true } );
177
185
  } );
178
186
 
179
- it( 'steps.js: rejects require of steps/evaluators/workflow; allows other require', async () => {
180
- const dir = mkdtempSync( join( tmpdir(), 'steps-require-' ) );
181
- await expect( runLoader( join( dir, 'steps.js' ), 'const { S } = require("./steps.js");' ) )
182
- .rejects.toThrow( /Invalid (require|dependency) in steps\.js/ );
183
- await expect( runLoader( join( dir, 'steps.js' ), 'const { E } = require("./evaluators.js");' ) )
184
- .rejects.toThrow( /Invalid (require|dependency) in steps\.js/ );
185
- await expect( runLoader( join( dir, 'steps.js' ), 'const W = require("./workflow.js");' ) )
186
- .rejects.toThrow( /Invalid (require|dependency) in steps\.js/ );
187
+ it( 'steps.js: allows require of steps/evaluators/workflow (no import restrictions)', async () => {
188
+ const dir = mkdtempSync( join( tmpdir(), 'steps-require-allow-' ) );
189
+ const result1 = await runLoader( join( dir, 'steps.js' ), 'const { S } = require("./steps.js");' );
190
+ expect( result1.warnings ).toHaveLength( 0 );
191
+ const result2 = await runLoader( join( dir, 'steps.js' ), 'const { E } = require("./evaluators.js");' );
192
+ expect( result2.warnings ).toHaveLength( 0 );
193
+ const result3 = await runLoader( join( dir, 'steps.js' ), 'const W = require("./workflow.js");' );
194
+ expect( result3.warnings ).toHaveLength( 0 );
187
195
  const ok = 'const util = require("./util.js");';
188
- await expect( runLoader( join( dir, 'steps.js' ), ok ) ).resolves.toBeTruthy();
196
+ const resultOk = await runLoader( join( dir, 'steps.js' ), ok );
197
+ expect( resultOk.warnings ).toHaveLength( 0 );
189
198
  rmSync( dir, { recursive: true, force: true } );
190
199
  } );
191
200
 
192
- it( 'evaluators.js: rejects require of steps/workflow; allows other require', async () => {
193
- const dir = mkdtempSync( join( tmpdir(), 'evals-require-' ) );
194
- await expect( runLoader( join( dir, 'evaluators.js' ), 'const { S } = require("./steps.js");' ) )
195
- .rejects.toThrow( /Invalid (require|dependency) in evaluators\.js/ );
196
- await expect( runLoader( join( dir, 'evaluators.js' ), 'const W = require("./workflow.js");' ) )
197
- .rejects.toThrow( /Invalid (require|dependency) in evaluators\.js/ );
201
+ it( 'evaluators.js: allows require of steps/workflow (no import restrictions)', async () => {
202
+ const dir = mkdtempSync( join( tmpdir(), 'evals-require-allow-' ) );
203
+ const result1 = await runLoader( join( dir, 'evaluators.js' ), 'const { S } = require("./steps.js");' );
204
+ expect( result1.warnings ).toHaveLength( 0 );
205
+ const result2 = await runLoader( join( dir, 'evaluators.js' ), 'const W = require("./workflow.js");' );
206
+ expect( result2.warnings ).toHaveLength( 0 );
198
207
  const ok = 'const util = require("./util.js");';
199
- await expect( runLoader( join( dir, 'evaluators.js' ), ok ) ).resolves.toBeTruthy();
208
+ const resultOk = await runLoader( join( dir, 'evaluators.js' ), ok );
209
+ expect( resultOk.warnings ).toHaveLength( 0 );
200
210
  rmSync( dir, { recursive: true, force: true } );
201
211
  } );
202
212
 
@@ -316,48 +326,48 @@ describe( 'workflow_validator loader', () => {
316
326
  } );
317
327
  } );
318
328
 
319
- describe( 'activity isolation - shared imports', () => {
320
- it( 'steps.ts: rejects imports from ../../shared/steps/common.js (activity isolation)', async () => {
321
- const dir = mkdtempSync( join( tmpdir(), 'steps-shared-steps-reject-' ) );
329
+ describe( 'cross-component imports - now allowed (no import restrictions)', () => {
330
+ it( 'steps.ts: allows imports from ../../shared/steps/common.js', async () => {
331
+ const dir = mkdtempSync( join( tmpdir(), 'steps-shared-steps-allow-' ) );
322
332
  mkdirSync( join( dir, 'workflows', 'my_workflow' ), { recursive: true } );
323
333
  mkdirSync( join( dir, 'shared', 'steps' ), { recursive: true } );
324
334
  writeFileSync( join( dir, 'shared', 'steps', 'common.js' ), 'export const commonStep = step({ name: "common" });\n' );
325
335
  const src = 'import { commonStep } from "../../shared/steps/common.js";';
326
- await expect( runLoader( join( dir, 'workflows', 'my_workflow', 'steps.js' ), src ) )
327
- .rejects.toThrow( /Invalid (import|imports|dependency) in steps\.js/ );
336
+ const result = await runLoader( join( dir, 'workflows', 'my_workflow', 'steps.js' ), src );
337
+ expect( result.warnings ).toHaveLength( 0 );
328
338
  rmSync( dir, { recursive: true, force: true } );
329
339
  } );
330
340
 
331
- it( 'steps.ts: rejects imports from ../../shared/evaluators/quality.js (activity isolation)', async () => {
332
- const dir = mkdtempSync( join( tmpdir(), 'steps-shared-evals-reject-' ) );
341
+ it( 'steps.ts: allows imports from ../../shared/evaluators/quality.js', async () => {
342
+ const dir = mkdtempSync( join( tmpdir(), 'steps-shared-evals-allow-' ) );
333
343
  mkdirSync( join( dir, 'workflows', 'my_workflow' ), { recursive: true } );
334
344
  mkdirSync( join( dir, 'shared', 'evaluators' ), { recursive: true } );
335
345
  writeFileSync( join( dir, 'shared', 'evaluators', 'quality.js' ), 'export const qualityEval = evaluator({ name: "quality" });\n' );
336
346
  const src = 'import { qualityEval } from "../../shared/evaluators/quality.js";';
337
- await expect( runLoader( join( dir, 'workflows', 'my_workflow', 'steps.js' ), src ) )
338
- .rejects.toThrow( /Invalid (import|imports|dependency) in steps\.js/ );
347
+ const result = await runLoader( join( dir, 'workflows', 'my_workflow', 'steps.js' ), src );
348
+ expect( result.warnings ).toHaveLength( 0 );
339
349
  rmSync( dir, { recursive: true, force: true } );
340
350
  } );
341
351
 
342
- it( 'evaluators.ts: rejects imports from ../../shared/steps/common.js (activity isolation)', async () => {
343
- const dir = mkdtempSync( join( tmpdir(), 'evals-shared-steps-reject-' ) );
352
+ it( 'evaluators.ts: allows imports from ../../shared/steps/common.js', async () => {
353
+ const dir = mkdtempSync( join( tmpdir(), 'evals-shared-steps-allow-' ) );
344
354
  mkdirSync( join( dir, 'workflows', 'my_workflow' ), { recursive: true } );
345
355
  mkdirSync( join( dir, 'shared', 'steps' ), { recursive: true } );
346
356
  writeFileSync( join( dir, 'shared', 'steps', 'common.js' ), 'export const commonStep = step({ name: "common" });\n' );
347
357
  const src = 'import { commonStep } from "../../shared/steps/common.js";';
348
- await expect( runLoader( join( dir, 'workflows', 'my_workflow', 'evaluators.js' ), src ) )
349
- .rejects.toThrow( /Invalid (import|imports|dependency) in evaluators\.js/ );
358
+ const result = await runLoader( join( dir, 'workflows', 'my_workflow', 'evaluators.js' ), src );
359
+ expect( result.warnings ).toHaveLength( 0 );
350
360
  rmSync( dir, { recursive: true, force: true } );
351
361
  } );
352
362
 
353
- it( 'evaluators.ts: rejects imports from ../../shared/evaluators/other.js (activity isolation)', async () => {
354
- const dir = mkdtempSync( join( tmpdir(), 'evals-shared-evals-reject-' ) );
363
+ it( 'evaluators.ts: allows imports from ../../shared/evaluators/other.js', async () => {
364
+ const dir = mkdtempSync( join( tmpdir(), 'evals-shared-evals-allow-' ) );
355
365
  mkdirSync( join( dir, 'workflows', 'my_workflow' ), { recursive: true } );
356
366
  mkdirSync( join( dir, 'shared', 'evaluators' ), { recursive: true } );
357
367
  writeFileSync( join( dir, 'shared', 'evaluators', 'other.js' ), 'export const otherEval = evaluator({ name: "other" });\n' );
358
368
  const src = 'import { otherEval } from "../../shared/evaluators/other.js";';
359
- await expect( runLoader( join( dir, 'workflows', 'my_workflow', 'evaluators.js' ), src ) )
360
- .rejects.toThrow( /Invalid (import|imports|dependency) in evaluators\.js/ );
369
+ const result = await runLoader( join( dir, 'workflows', 'my_workflow', 'evaluators.js' ), src );
370
+ expect( result.warnings ).toHaveLength( 0 );
361
371
  rmSync( dir, { recursive: true, force: true } );
362
372
  } );
363
373
  } );