@outputai/core 0.9.3-next.01f20d3.0 → 0.9.3-next.105840b.0
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
|
@@ -8,25 +8,12 @@ import { deepMerge } from '#helpers/object';
|
|
|
8
8
|
import { defaultOptions } from './workflow_activity_options.js';
|
|
9
9
|
import { createWorkflow } from '#helpers/component';
|
|
10
10
|
import {
|
|
11
|
-
ACTIVITY_WRAPPER_VERSION_FIELD,
|
|
12
11
|
ACTIVITY_GET_TRACE_DESTINATIONS,
|
|
13
12
|
METADATA_ACCESS_SYMBOL,
|
|
14
13
|
SHARED_STEP_PREFIX,
|
|
15
14
|
WORKFLOW_WRAPPER_VERSION_FIELD
|
|
16
15
|
} from '#consts';
|
|
17
16
|
|
|
18
|
-
/**
|
|
19
|
-
* @temp
|
|
20
|
-
* This is to keep backwards compatibility [OUT-468]
|
|
21
|
-
*/
|
|
22
|
-
const parseActivityOutput = p => Object.hasOwn( p ?? {}, ACTIVITY_WRAPPER_VERSION_FIELD ) ? p.output : p;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @temp This is a TEMP fallback method to allow workflow child checks on replays without memo. [OUT-468]
|
|
26
|
-
* This workflows for most scenarios, only does not supports recursion with the same name.
|
|
27
|
-
*/
|
|
28
|
-
const checkChildFallback = ( { workflowType, name, aliases } ) => workflowType !== name && !aliases.includes( workflowType );
|
|
29
|
-
|
|
30
17
|
/**
|
|
31
18
|
* Create a new workflow and return a wrapper function around its fn handler
|
|
32
19
|
*/
|
|
@@ -54,12 +41,11 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
|
|
|
54
41
|
return output;
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
const { workflowId,
|
|
44
|
+
const { workflowId, memo, root } = workflowInfo();
|
|
58
45
|
|
|
59
46
|
// if the stack already includes this workflowId, means the workflow() function was called
|
|
60
47
|
// from within a running workflow, meaning it is suppose to start a child workflow
|
|
61
|
-
const isChild = Array.isArray( memo.stack ) ? memo.stack.includes( workflowId ) :
|
|
62
|
-
checkChildFallback( { workflowType, aliases, name } );
|
|
48
|
+
const isChild = Array.isArray( memo.stack ) ? memo.stack.includes( workflowId ) : false;
|
|
63
49
|
|
|
64
50
|
if ( isChild ) {
|
|
65
51
|
const result = await executeChild( name, {
|
|
@@ -87,13 +73,13 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
|
|
|
87
73
|
}
|
|
88
74
|
|
|
89
75
|
const steps = proxyActivities( memo.activityOptions );
|
|
90
|
-
const traceDest = isRoot &&
|
|
76
|
+
const traceDest = isRoot && ( await steps[ACTIVITY_GET_TRACE_DESTINATIONS]( memo.traceInfo ) ).output;
|
|
91
77
|
|
|
92
78
|
try {
|
|
93
79
|
validator.validateInput( input );
|
|
94
80
|
|
|
95
81
|
// Creates an activity caller based on a prefix
|
|
96
|
-
const createCaller = prefix => async ( t, ...args ) =>
|
|
82
|
+
const createCaller = prefix => async ( t, ...args ) => ( await steps[`${prefix}#${t}`]( ...args ) ).output;
|
|
97
83
|
|
|
98
84
|
// This are functions used by the AST to replace direct activity (step/evaluator) calls
|
|
99
85
|
const dispatchers = {
|
|
@@ -373,30 +373,6 @@ describe( 'workflow()', () => {
|
|
|
373
373
|
expect( getTraceDestinations ).toHaveBeenCalledWith( info.memo.traceInfo );
|
|
374
374
|
} );
|
|
375
375
|
|
|
376
|
-
it( 'falls back to workflow type matching when replaying an old child call without memo.stack', async () => {
|
|
377
|
-
const { workflow } = await import( './workflow.js' );
|
|
378
|
-
const { ParentClosePolicy } = await import( '@temporalio/workflow' );
|
|
379
|
-
setWorkflowInfo( { workflowType: 'old_parent_wf', memo: { traceInfo: { workflowId: 'root-workflow' } } } );
|
|
380
|
-
executeChildMock.mockResolvedValueOnce( { output: { child: 'replayed' } } );
|
|
381
|
-
const fn = vi.fn();
|
|
382
|
-
|
|
383
|
-
const wf = workflow( workflowDefinition( {
|
|
384
|
-
name: 'old_child_wf',
|
|
385
|
-
inputSchema: z.object( { id: z.number() } ),
|
|
386
|
-
outputSchema: z.object( { child: z.string() } ),
|
|
387
|
-
fn
|
|
388
|
-
} ) );
|
|
389
|
-
|
|
390
|
-
await expect( wf( { id: 7 } ) ).resolves.toEqual( { child: 'replayed' } );
|
|
391
|
-
expect( fn ).not.toHaveBeenCalled();
|
|
392
|
-
expect( executeChildMock ).toHaveBeenCalledWith( 'old_child_wf', expect.objectContaining( {
|
|
393
|
-
args: [ { id: 7 } ],
|
|
394
|
-
parentClosePolicy: ParentClosePolicy.TERMINATE,
|
|
395
|
-
memo: { traceInfo: { workflowId: 'root-workflow' } }
|
|
396
|
-
} ) );
|
|
397
|
-
expect( proxyActivitiesMock ).not.toHaveBeenCalled();
|
|
398
|
-
} );
|
|
399
|
-
|
|
400
376
|
it( 'does not fallback to child execution when the replayed workflow type matches an alias', async () => {
|
|
401
377
|
const { workflow } = await import( './workflow.js' );
|
|
402
378
|
setWorkflowInfo( { workflowType: 'old_root_wf', memo: {} } );
|
|
@@ -531,43 +507,6 @@ describe( 'workflow()', () => {
|
|
|
531
507
|
} );
|
|
532
508
|
} );
|
|
533
509
|
|
|
534
|
-
it( 'supports old unwrapped trace destination activity results during replay', async () => {
|
|
535
|
-
const { workflow } = await import( './workflow.js' );
|
|
536
|
-
setWorkflowInfo( { workflowType: 'old_trace_payload_wf' } );
|
|
537
|
-
mockActivities( {
|
|
538
|
-
[ACTIVITY_GET_TRACE_DESTINATIONS]: vi.fn().mockResolvedValue( { local: '/tmp/old-trace' } )
|
|
539
|
-
} );
|
|
540
|
-
|
|
541
|
-
const wf = workflow( workflowDefinition( {
|
|
542
|
-
name: 'old_trace_payload_wf',
|
|
543
|
-
outputSchema: z.object( { ok: z.boolean() } ),
|
|
544
|
-
fn: async () => ( { ok: true } )
|
|
545
|
-
} ) );
|
|
546
|
-
|
|
547
|
-
await expect( wf( {} ) ).resolves.toEqual( {
|
|
548
|
-
[WORKFLOW_WRAPPER_VERSION_FIELD]: 1,
|
|
549
|
-
output: { ok: true },
|
|
550
|
-
trace: { destinations: { local: '/tmp/old-trace' } }
|
|
551
|
-
} );
|
|
552
|
-
} );
|
|
553
|
-
|
|
554
|
-
it( 'supports old null trace destination activity results during replay', async () => {
|
|
555
|
-
const { workflow } = await import( './workflow.js' );
|
|
556
|
-
setWorkflowInfo( { workflowType: 'old_null_trace_payload_wf' } );
|
|
557
|
-
mockActivities( { [ACTIVITY_GET_TRACE_DESTINATIONS]: vi.fn().mockResolvedValue( null ) } );
|
|
558
|
-
|
|
559
|
-
const wf = workflow( workflowDefinition( {
|
|
560
|
-
name: 'old_null_trace_payload_wf',
|
|
561
|
-
outputSchema: z.object( { ok: z.boolean() } ),
|
|
562
|
-
fn: async () => ( { ok: true } )
|
|
563
|
-
} ) );
|
|
564
|
-
|
|
565
|
-
await expect( wf( {} ) ).resolves.toEqual( {
|
|
566
|
-
[WORKFLOW_WRAPPER_VERSION_FIELD]: 1,
|
|
567
|
-
output: { ok: true }
|
|
568
|
-
} );
|
|
569
|
-
} );
|
|
570
|
-
|
|
571
510
|
it( 'validates input and output inside workflow context', async () => {
|
|
572
511
|
const { workflow } = await import( './workflow.js' );
|
|
573
512
|
const inputError = new ValidationError( 'invalid workflow input' );
|
|
@@ -656,34 +595,6 @@ describe( 'workflow()', () => {
|
|
|
656
595
|
expect( sharedStep ).toHaveBeenCalledWith();
|
|
657
596
|
expect( sharedEvaluator ).toHaveBeenCalledWith( { x: 1 } );
|
|
658
597
|
} );
|
|
659
|
-
|
|
660
|
-
it( 'supports old unwrapped step and evaluator activity results during replay', async () => {
|
|
661
|
-
const { workflow } = await import( './workflow.js' );
|
|
662
|
-
setWorkflowInfo( { workflowType: 'old_activity_payload_wf' } );
|
|
663
|
-
const step = vi.fn().mockResolvedValue( 'legacy-step-output' );
|
|
664
|
-
const evaluator = vi.fn().mockResolvedValue( 'legacy-eval-output' );
|
|
665
|
-
mockActivities( {
|
|
666
|
-
[ACTIVITY_GET_TRACE_DESTINATIONS]: vi.fn().mockResolvedValue( activityOutput( null ) ),
|
|
667
|
-
'old_activity_payload_wf#stepA': step,
|
|
668
|
-
'old_activity_payload_wf#evalA': evaluator
|
|
669
|
-
} );
|
|
670
|
-
|
|
671
|
-
const wf = workflow( workflowDefinition( {
|
|
672
|
-
name: 'old_activity_payload_wf',
|
|
673
|
-
outputSchema: z.object( { stepResult: z.string(), evalResult: z.string() } ),
|
|
674
|
-
async fn() {
|
|
675
|
-
return {
|
|
676
|
-
stepResult: await this.invokeStep( 'stepA' ),
|
|
677
|
-
evalResult: await this.invokeEvaluator( 'evalA' )
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
} ) );
|
|
681
|
-
|
|
682
|
-
await expect( wf( {} ) ).resolves.toEqual( {
|
|
683
|
-
[WORKFLOW_WRAPPER_VERSION_FIELD]: 1,
|
|
684
|
-
output: { stepResult: 'legacy-step-output', evalResult: 'legacy-eval-output' }
|
|
685
|
-
} );
|
|
686
|
-
} );
|
|
687
598
|
} );
|
|
688
599
|
|
|
689
600
|
describe( 'error handling', () => {
|