@output.ai/core 0.1.10 → 0.1.12
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
package/src/index.d.ts
CHANGED
|
@@ -21,15 +21,17 @@ export { z } from 'zod';
|
|
|
21
21
|
type AnyZodSchema = z.ZodType<any, any, any>;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
* Activity
|
|
25
|
-
*
|
|
26
|
-
|
|
27
|
-
export type Options = { retry?: ActivityOptions['retry'] };
|
|
28
|
-
|
|
29
|
-
/**
|
|
24
|
+
* Activity options accepted by step/evaluator/workflow definitions.
|
|
25
|
+
* Exposes supported Temporal ActivityOptions.
|
|
26
|
+
*
|
|
30
27
|
* @typedef {object} Options
|
|
31
|
-
* @
|
|
28
|
+
* @description Exposes supported Temporal ActivityOptions
|
|
32
29
|
*/
|
|
30
|
+
export type Options = Omit<ActivityOptions, 'versioningIntent' | 'taskQueue' | 'allowEagerDispatch'>;
|
|
31
|
+
|
|
32
|
+
export type WorkflowCallConfig = {
|
|
33
|
+
options?: Options
|
|
34
|
+
};
|
|
33
35
|
|
|
34
36
|
/*
|
|
35
37
|
╭─────────╮
|
|
@@ -165,7 +167,7 @@ export function workflow<
|
|
|
165
167
|
outputSchema: OutputSchema,
|
|
166
168
|
fn: ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>,
|
|
167
169
|
options?: Options
|
|
168
|
-
} ): ( input: z.infer<InputSchema
|
|
170
|
+
} ): ( input: z.infer<InputSchema>, extra?: WorkflowCallConfig ) => Promise<z.infer<OutputSchema>>;
|
|
169
171
|
|
|
170
172
|
/**
|
|
171
173
|
* Creates a workflow orchestrator with defined schema for input only.
|
|
@@ -186,7 +188,7 @@ export function workflow<
|
|
|
186
188
|
inputSchema: InputSchema,
|
|
187
189
|
fn: ( input: z.infer<InputSchema> ) => Promise<void>,
|
|
188
190
|
options?: Options
|
|
189
|
-
} ): ( input: z.infer<InputSchema
|
|
191
|
+
} ): ( input: z.infer<InputSchema>, extra?: WorkflowCallConfig ) => Promise<void>;
|
|
190
192
|
|
|
191
193
|
/**
|
|
192
194
|
* Creates a workflow orchestrator with defined schema for output only.
|
|
@@ -207,7 +209,7 @@ export function workflow<
|
|
|
207
209
|
outputSchema: OutputSchema,
|
|
208
210
|
fn: () => Promise<z.infer<OutputSchema>>,
|
|
209
211
|
options?: Options
|
|
210
|
-
} ): () => Promise<z.infer<OutputSchema>>;
|
|
212
|
+
} ): ( input?: undefined | null, extra?: WorkflowCallConfig ) => Promise<z.infer<OutputSchema>>;
|
|
211
213
|
|
|
212
214
|
/**
|
|
213
215
|
* Creates a workflow orchestrator without defined schemas.
|
|
@@ -224,7 +226,7 @@ export function workflow( options : {
|
|
|
224
226
|
description?: string,
|
|
225
227
|
fn: () => Promise<void>,
|
|
226
228
|
options?: Options
|
|
227
|
-
} ): () => Promise<void>;
|
|
229
|
+
} ): ( input?: undefined | null, extra?: WorkflowCallConfig ) => Promise<void>;
|
|
228
230
|
|
|
229
231
|
/*
|
|
230
232
|
╭───────────────────╮
|
|
@@ -17,10 +17,16 @@ const refineSchema = ( value, ctx ) => {
|
|
|
17
17
|
} );
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
export const
|
|
20
|
+
export const durationSchema = z.union( [ z.string().regex(
|
|
21
21
|
/^(\d+)(ms|s|m|h|d)$/,
|
|
22
22
|
'Expected duration like "500ms", "10s", "5m", "2h", or "1d"'
|
|
23
|
-
);
|
|
23
|
+
), z.number() ] );
|
|
24
|
+
|
|
25
|
+
export const prioritySchema = z.object( {
|
|
26
|
+
fairnessKey: z.string().optional(),
|
|
27
|
+
fairnessWeight: z.number().min( 0.0001 ).max( 1000 ).optional(),
|
|
28
|
+
priorityKey: z.number().min( 1 ).optional()
|
|
29
|
+
} );
|
|
24
30
|
|
|
25
31
|
const stepAndWorkflowSchema = z.strictObject( {
|
|
26
32
|
name: z.string().regex( /^[a-z_][a-z0-9_]*$/i ),
|
|
@@ -29,13 +35,21 @@ const stepAndWorkflowSchema = z.strictObject( {
|
|
|
29
35
|
outputSchema: z.any().optional().superRefine( refineSchema ),
|
|
30
36
|
fn: z.function(),
|
|
31
37
|
options: z.strictObject( {
|
|
38
|
+
activityId: z.string().optional(),
|
|
39
|
+
cancellationType: z.enum( [ 'TRY_CANCEL', 'WAIT_CANCELLATION_COMPLETED', 'ABANDON' ] ).optional(),
|
|
40
|
+
heartbeatTimeout: durationSchema.optional(),
|
|
41
|
+
priority: prioritySchema.optional(),
|
|
32
42
|
retry: z.strictObject( {
|
|
33
|
-
initialInterval:
|
|
43
|
+
initialInterval: durationSchema.optional(),
|
|
34
44
|
backoffCoefficient: z.number().gte( 1 ).optional(),
|
|
35
|
-
maximumInterval:
|
|
45
|
+
maximumInterval: durationSchema.optional(),
|
|
36
46
|
maximumAttempts: z.number().gte( 1 ).int().optional(),
|
|
37
47
|
nonRetryableErrorTypes: z.array( z.string() ).optional()
|
|
38
|
-
} ).optional()
|
|
48
|
+
} ).optional(),
|
|
49
|
+
scheduleToCloseTimeout: durationSchema.optional(),
|
|
50
|
+
scheduleToStartTimeout: durationSchema.optional(),
|
|
51
|
+
startToCloseTimeout: durationSchema.optional(),
|
|
52
|
+
summary: z.string().optional()
|
|
39
53
|
} ).optional()
|
|
40
54
|
} );
|
|
41
55
|
|
|
@@ -82,6 +82,71 @@ describe( 'interface/validator', () => {
|
|
|
82
82
|
expect( () => validateStep( args ) ).not.toThrow();
|
|
83
83
|
} );
|
|
84
84
|
|
|
85
|
+
it( 'passes with options.activityId as string', () => {
|
|
86
|
+
expect( () => validateStep( { ...validArgs, options: { activityId: 'act-123' } } ) ).not.toThrow();
|
|
87
|
+
} );
|
|
88
|
+
|
|
89
|
+
it( 'rejects non-string options.activityId', () => {
|
|
90
|
+
expect( () => validateStep( { ...validArgs, options: { activityId: 123 } } ) ).toThrow( StaticValidationError );
|
|
91
|
+
} );
|
|
92
|
+
|
|
93
|
+
it( 'passes with valid options.cancellationType values', () => {
|
|
94
|
+
for ( const v of [ 'TRY_CANCEL', 'WAIT_CANCELLATION_COMPLETED', 'ABANDON' ] ) {
|
|
95
|
+
expect( () => validateStep( { ...validArgs, options: { cancellationType: v } } ) ).not.toThrow();
|
|
96
|
+
}
|
|
97
|
+
} );
|
|
98
|
+
|
|
99
|
+
it( 'rejects invalid options.cancellationType', () => {
|
|
100
|
+
expect( () => validateStep( { ...validArgs, options: { cancellationType: 'INVALID' } } ) ).toThrow( StaticValidationError );
|
|
101
|
+
} );
|
|
102
|
+
|
|
103
|
+
it( 'accepts duration fields in options', () => {
|
|
104
|
+
const options = {
|
|
105
|
+
heartbeatTimeout: '1s',
|
|
106
|
+
scheduleToCloseTimeout: '2m',
|
|
107
|
+
scheduleToStartTimeout: '3m',
|
|
108
|
+
startToCloseTimeout: '4m'
|
|
109
|
+
};
|
|
110
|
+
expect( () => validateStep( { ...validArgs, options } ) ).not.toThrow();
|
|
111
|
+
} );
|
|
112
|
+
|
|
113
|
+
it( 'rejects invalid duration string in heartbeatTimeout', () => {
|
|
114
|
+
expect( () => validateStep( { ...validArgs, options: { heartbeatTimeout: '5x' } } ) ).toThrow( StaticValidationError );
|
|
115
|
+
} );
|
|
116
|
+
|
|
117
|
+
it( 'passes with options.summary string', () => {
|
|
118
|
+
expect( () => validateStep( { ...validArgs, options: { summary: 'brief' } } ) ).not.toThrow();
|
|
119
|
+
} );
|
|
120
|
+
|
|
121
|
+
it( 'rejects non-string options.summary', () => {
|
|
122
|
+
expect( () => validateStep( { ...validArgs, options: { summary: 42 } } ) ).toThrow( StaticValidationError );
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
it( 'passes with options.priority valid payload', () => {
|
|
126
|
+
const options = {
|
|
127
|
+
priority: {
|
|
128
|
+
fairnessKey: 'user-1',
|
|
129
|
+
fairnessWeight: 1.5,
|
|
130
|
+
priorityKey: 10
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
expect( () => validateStep( { ...validArgs, options } ) ).not.toThrow();
|
|
134
|
+
} );
|
|
135
|
+
|
|
136
|
+
it( 'rejects invalid options.priority values', () => {
|
|
137
|
+
const options = { priority: { fairnessWeight: 0, priorityKey: 0 } };
|
|
138
|
+
expect( () => validateStep( { ...validArgs, options } ) ).toThrow( StaticValidationError );
|
|
139
|
+
} );
|
|
140
|
+
|
|
141
|
+
it( 'rejects invalid options.retry values', () => {
|
|
142
|
+
const options = { retry: { backoffCoefficient: 0.5, maximumAttempts: 0, nonRetryableErrorTypes: [ 1 ] } };
|
|
143
|
+
expect( () => validateStep( { ...validArgs, options } ) ).toThrow( StaticValidationError );
|
|
144
|
+
} );
|
|
145
|
+
|
|
146
|
+
it( 'rejects unknown keys inside options due to strictObject', () => {
|
|
147
|
+
expect( () => validateStep( { ...validArgs, options: { unknownKey: true } } ) ).toThrow( StaticValidationError );
|
|
148
|
+
} );
|
|
149
|
+
|
|
85
150
|
it( 'rejects unknown top-level keys due to strictObject', () => {
|
|
86
151
|
expect( () => validateStep( { ...validArgs, extra: 123 } ) ).toThrow( StaticValidationError );
|
|
87
152
|
} );
|
|
@@ -59,11 +59,16 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
|
|
|
59
59
|
invokeSharedStep: async ( stepName, input, options ) => steps[`${SHARED_STEP_PREFIX}#${stepName}`]( input, options ),
|
|
60
60
|
invokeEvaluator: async ( evaluatorName, input, options ) => steps[`${workflowPath}#${evaluatorName}`]( input, options ),
|
|
61
61
|
|
|
62
|
-
startWorkflow: async ( childName, input ) => {
|
|
62
|
+
startWorkflow: async ( childName, input, extra = {} ) => {
|
|
63
63
|
return executeChild( childName, {
|
|
64
64
|
args: input ? [ input ] : [],
|
|
65
65
|
workflowId: `${workflowId}-${childName}-${Date.now()}`,
|
|
66
|
-
memo: {
|
|
66
|
+
memo: {
|
|
67
|
+
executionContext,
|
|
68
|
+
parentId: workflowId,
|
|
69
|
+
// new configuration for activities of the child workflow, this will be omitted so it will use what that workflow have defined
|
|
70
|
+
...( extra?.options && { activityOptions: mergeActivityOptions( activityOptions, extra.options ) } )
|
|
71
|
+
}
|
|
67
72
|
} );
|
|
68
73
|
}
|
|
69
74
|
}, input );
|