@output.ai/core 0.1.15 → 0.1.17

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.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "The core module of the output framework",
5
5
  "type": "module",
6
6
  "exports": {
package/src/index.d.ts CHANGED
@@ -1,49 +1,31 @@
1
- // Import Zod types for dual schema support
2
1
  import type { z } from 'zod';
3
2
  import type { ActivityOptions } from '@temporalio/workflow';
4
3
 
5
- // Re-export Zod for consumers to use
4
+ /**
5
+ * Expose z from Zod as a convenience.
6
+ */
6
7
  export { z } from 'zod';
7
8
 
9
+ /*
10
+ ╭─────────────────────────╮
11
+ │ C O M M O N T Y P E S │╮
12
+ ╰─────────────────────────╯│
13
+ ╰─────────────────────────╯
14
+ */
15
+
8
16
  /**
9
17
  * Type alias for any Zod schema type.
10
- *
11
- * Note: The use of `any` here is intentional and necessary. Zod's ZodType has three
12
- * generic parameters (Output, Def, Input) that vary based on the specific schema type.
13
- * When we want to accept ANY Zod schema (string, number, object, etc.), we must use
14
- * `any` for these parameters. Using `unknown` would be too restrictive and would
15
- * break Zod's type inference system.
16
- *
17
- * This is a common pattern in TypeScript when dealing with highly generic types,
18
- * and Zod itself uses this pattern internally.
19
18
  */
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- type AnyZodSchema = z.ZodType<any, any, any>;
19
+ export type AnyZodSchema = z.ZodType<any, any, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
22
20
 
23
21
  /**
24
- * Activity options accepted by step/evaluator/workflow definitions.
25
- * Exposes supported Temporal ActivityOptions.
22
+ * Native Temporal configurations for activities.
26
23
  *
27
- * @description Exposes supported Temporal ActivityOptions
28
- */
29
- export type Options = Omit<ActivityOptions, 'versioningIntent' | 'taskQueue' | 'allowEagerDispatch'>;
30
-
31
- /**
32
- * The last argument when calling workflows is used to configure it
24
+ * All native options are accepted except 'versioningIntent', 'taskQueue', 'allowEagerDispatch'.
25
+ *
26
+ * @see {@link https://typescript.temporal.io/api/interfaces/common.ActivityOptions}
33
27
  */
34
- export type WorkflowCallConfig = {
35
-
36
- /**
37
- * Temporal Activity Options
38
- */
39
- options?: Options,
40
-
41
- /**
42
- * Whether this workflow will run detached or not.
43
- * Detached workflows called without explicitly awaiting for the result will be "fire-an-forget", outliving the parent.
44
- */
45
- detached?: boolean
46
- };
28
+ export type TemporalActivityOptions = Omit<ActivityOptions, 'versioningIntent' | 'taskQueue' | 'allowEagerDispatch'>;
47
29
 
48
30
  /*
49
31
  ╭─────────╮
@@ -52,96 +34,127 @@ export type WorkflowCallConfig = {
52
34
  ╰─────────╯
53
35
  */
54
36
 
55
- /*
56
- * There are 4 overloads of the "step" function:
57
- * - with fn receiving input and returning output;
58
- * - with fn receiving input and returning void;
59
- * - with fn receiving void and returning output;
60
- * - with fn receiving void and returning void;
61
- */
62
-
63
- /**
64
- * Creates logical unit of work defined schema for both input and output.
65
- *
66
- * @param {object} options - Step options
67
- * @param {string} options.name - Human-readable step name (only letters, numbers and "_")
68
- * @param {string} [options.description] - Description of the step
69
- * @param {z.ZodType} options.inputSchema - Zod schema for the fn input
70
- * @param {z.ZodType} options.outputSchema - Zod schema for the fn output
71
- * @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
72
- * @param {Options} [options.options] - Activity retry options
73
- * @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
74
- */
75
- export async function step<
76
- InputSchema extends AnyZodSchema,
77
- OutputSchema extends AnyZodSchema
78
- >( options: {
79
- name: string;
80
- description?: string;
81
- inputSchema: InputSchema;
82
- outputSchema: OutputSchema;
83
- fn: ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>;
84
- options?: Options;
85
- } ): ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>;
86
-
87
37
  /**
88
- * Creates logical unit of work with defined schema for input only.
89
- *
90
- * @param {object} options - Step options
91
- * @param {string} options.name - Human-readable step name (only letters, numbers and "_")
92
- * @param {string} [options.description] - Description of the step
93
- * @param {z.ZodType} options.inputSchema - Zod schema for the fn input
94
- * @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<void>`
95
- * @param {Options} [options.options] - Activity retry options
96
- * @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<void>`
38
+ * The handler function of a step.
39
+ *
40
+ * @param input - The step input; it matches the schema defined by `inputSchema`.
41
+ *
42
+ * @returns A value matching the schema defined by `outputSchema`.
97
43
  */
98
- export async function step<
99
- InputSchema extends AnyZodSchema
100
- >( options: {
101
- name: string;
102
- description?: string;
103
- inputSchema: InputSchema;
104
- fn: ( input: z.infer<InputSchema> ) => Promise<void>;
105
- options?: Options;
106
- } ): ( input: z.infer<InputSchema> ) => Promise<void>;
44
+ export type StepFunction<
45
+ InputSchema extends AnyZodSchema | undefined = undefined,
46
+ OutputSchema extends AnyZodSchema | undefined = undefined
47
+ > = InputSchema extends AnyZodSchema ?
48
+ ( input: z.infer<InputSchema> ) => Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void> :
49
+ () => Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void>;
107
50
 
108
51
  /**
109
- * Creates logical unit of work with defined schema for output only.
110
- *
111
- * @param {object} options - Step options
112
- * @param {string} options.name - Human-readable step name (only letters, numbers and "_")
113
- * @param {string} [options.description] - Description of the step
114
- * @param {z.ZodType} options.outputSchema - Zod schema for the fn output
115
- * @param {function} options.fn - The function logic: `() => Promise<z.infer<OutputSchema>>`
116
- * @param {Options} [options.options] - Activity retry options
117
- * @returns {function} Function with signature: `() => Promise<z.infer<OutputSchema>>`
52
+ * A wrapper around the user defined `fn` handler function.
53
+ *
54
+ * It accepts the same input and returns the same value, calling the user function inside.
55
+ *
56
+ * It adds input and output validation based on the `inputSchema`, `outputSchema`.
57
+ *
58
+ * @param input - The Step input; it matches the schema defined by `inputSchema`.
59
+ * @returns A value matching the schema defined by `outputSchema`.
118
60
  */
119
- export async function step<
120
- OutputSchema extends AnyZodSchema
121
- >( options: {
122
- name: string;
123
- description?: string;
124
- outputSchema: OutputSchema;
125
- fn: () => Promise<z.infer<OutputSchema>>;
126
- options?: Options;
127
- } ): () => Promise<z.infer<OutputSchema>>;
61
+ export type StepFunctionWrapper<StepFunction> =
62
+ Parameters<StepFunction> extends [infer Input] ?
63
+ ( input: Input ) => ReturnType<StepFunction> :
64
+ () => ReturnType<StepFunction>;
128
65
 
129
66
  /**
130
- * Creates logical unit of work without schemas.
131
- *
132
- * @param {object} options - Step options
133
- * @param {string} options.name - Human-readable step name (only letters, numbers and "_")
134
- * @param {string} [options.description] - Description of the step
135
- * @param {function} options.fn - The function logic: `() => Promise<void>`
136
- * @param {Options} [options.options] - Activity retry options
137
- * @returns {function} Function with signature: `() => Promise<void>`
67
+ * Creates a step.
68
+ *
69
+ * A step is a logical unit of work that can perform I/O. It is translated to a Temporal Activity.
70
+ *
71
+ * The step logic is defined in the `fn` handler function.
72
+ *
73
+ * The schema of the input that the function receives as the first argument is defined by the `inputSchema` option.
74
+ *
75
+ * The output of the `fn` handler must match the schema defined by `outputSchema`; otherwise, a validation error is raised.
76
+ *
77
+ * @example
78
+ * ```
79
+ * step( {
80
+ * name: 'process',
81
+ * description: 'A generic process',
82
+ * inputSchema: z.object( {
83
+ * value: z.number()
84
+ * } ),
85
+ * outputSchema: z.string(),
86
+ * fn: async input => {
87
+ * const result = await ai.call( input.value );
88
+ * return result as string;
89
+ * }
90
+ * } )
91
+ * ```
92
+ *
93
+ * @example Step without outputSchema
94
+ * ```
95
+ * step( {
96
+ * name: 'process',
97
+ * description: 'A generic process',
98
+ * inputSchema: z.object( {
99
+ * value: z.number()
100
+ * } ),
101
+ * fn: async input => {
102
+ * await ai.call( input.value );
103
+ * }
104
+ * } )
105
+ * ```
106
+ *
107
+ * @example Step without inputSchema
108
+ * ```
109
+ * step( {
110
+ * name: 'process',
111
+ * description: 'A generic process',
112
+ * outputSchema: z.string(),
113
+ * fn: async () => {
114
+ * const result = await ai.call();
115
+ * return result as string;
116
+ * }
117
+ * } )
118
+ * ```
119
+ *
120
+ * @example Step without inputSchema and outputSchema
121
+ * ```
122
+ * step( {
123
+ * name: 'process',
124
+ * description: 'A generic process',
125
+ * fn: async () => {
126
+ * await ai.call();
127
+ * }
128
+ * } )
129
+ * ```
130
+ *
131
+ * @remarks
132
+ * - Never call another step from within a step.
133
+ * - Never call a workflow from within a step.
134
+ *
135
+ * @typeParam InputSchema - Zod schema for the step input
136
+ * @typeParam OutputSchema - Zod schema for the step output
137
+ *
138
+ * @param params - Step parameters
139
+ * @param params.name - Human-readable step name (must start with a letter or underscore, followed by letters, numbers, or underscores)
140
+ * @param params.description - Description of the step
141
+ * @param params.inputSchema - Zod schema for the `fn` input
142
+ * @param params.outputSchema - Zod schema for the `fn` output
143
+ * @param params.fn - A handler function containing the step code
144
+ * @param params.options - Temporal Activity options
145
+ * @returns The same handler function set at `fn`
138
146
  */
139
- export async function step( options: {
147
+ export declare function step<
148
+ InputSchema extends AnyZodSchema | undefined = undefined,
149
+ OutputSchema extends AnyZodSchema | undefined = undefined
150
+ >( params: {
140
151
  name: string;
141
152
  description?: string;
142
- fn: () => Promise<void>;
143
- options?: Options;
144
- } ): () => Promise<void>;
153
+ inputSchema?: InputSchema;
154
+ outputSchema?: OutputSchema;
155
+ fn: StepFunction<InputSchema, OutputSchema>;
156
+ options?: TemporalActivityOptions;
157
+ } ): StepFunctionWrapper<StepFunction<InputSchema, OutputSchema>>;
145
158
 
146
159
  /*
147
160
  ╭─────────────────╮
@@ -149,96 +162,236 @@ export async function step( options: {
149
162
  ╰─────────────────╯│
150
163
  ╰─────────────────╯
151
164
  */
152
- /*
153
- * There are 4 overloads of the "workflow" function:
154
- * - with fn receiving input and returning output;
155
- * - with fn receiving input and returning void;
156
- * - with fn receiving void and returning output;
157
- * - with fn receiving void and returning void;
165
+
166
+ /**
167
+ * Configuration for workflow invocations.
168
+ *
169
+ * Allows overriding Temporal Activity options for this workflow.
158
170
  */
171
+ export type WorkflowInvocationConfiguration = {
172
+
173
+ /**
174
+ * Native Temporal Activity options
175
+ */
176
+ options?: TemporalActivityOptions,
177
+
178
+ /**
179
+ * Configures whether this workflow runs detached.
180
+ * Detached workflows called without explicitly awaiting the result are "fire-and-forget" and may outlive the parent.
181
+ */
182
+ detached?: boolean
183
+ };
159
184
 
160
185
  /**
161
- * Creates a workflow orchestrator with defined schema for both input and output.
162
- *
163
- * @param {object} options - Workflow options
164
- * @param {string} options.name - Unique workflow name
165
- * @param {string} [options.description] - Description of the workflow
166
- * @param {z.ZodType} options.inputSchema - Zod schema for workflow input
167
- * @param {z.ZodType} options.outputSchema - Zod schema for workflow output
168
- * @param {function} options.fn - Workflow logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
169
- * @param {Options} [options.options] - Activity retry options
170
- * @returns {function} Callable workflow function: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
186
+ * The second argument passed to the workflow's `fn` function.
171
187
  */
172
- export function workflow<
173
- InputSchema extends AnyZodSchema,
174
- OutputSchema extends AnyZodSchema
175
- >( options : {
176
- name: string,
177
- description?: string,
178
- inputSchema: InputSchema,
179
- outputSchema: OutputSchema,
180
- fn: ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>,
181
- options?: Options
182
- } ): ( input: z.infer<InputSchema>, extra?: WorkflowCallConfig ) => Promise<z.infer<OutputSchema>>;
188
+ export type WorkflowContext<
189
+ InputSchema extends AnyZodSchema | undefined = undefined,
190
+ OutputSchema extends AnyZodSchema | undefined = undefined
191
+ > = {
192
+
193
+ /**
194
+ * Functions that allow fine control over the underlying Temporal workflows
195
+ */
196
+ control: {
197
+ /**
198
+ * Closes the current workflow execution successfully and creates a new workflow execution.
199
+ *
200
+ * The new workflow execution is in the same chain as the previous workflow, but it generates another trace file.
201
+ *
202
+ * It acts as a checkpoint when the workflow gets too long or approaches certain scaling limits.
203
+ *
204
+ * It accepts input with the same schema as the parent workflow function (`inputSchema`).
205
+ *
206
+ * Calling this function must be the last statement in the workflow, accompanied by a `return`:
207
+ *
208
+ * @example
209
+ * ```js
210
+ * return control.continueAsNew();
211
+ * ```
212
+ * Upon returning, the parent workflow execution closes without any output, and the new execution takes its place.
213
+ *
214
+ * The function's return type matches `outputSchema`; although no value is returned, the execution is replaced.
215
+ *
216
+ * @see {@link https://docs.temporal.io/develop/typescript/continue-as-new}
217
+ *
218
+ * @param input - The input for the new run. Omit when the workflow has no input schema.
219
+ * @returns The workflow output type for type-checking; never returns at runtime.
220
+ */
221
+ continueAsNew: InputSchema extends AnyZodSchema ?
222
+ ( input: z.infer<InputSchema> ) => ( OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void ) :
223
+ () => ( OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void ),
224
+
225
+ /** Indicates whether the Temporal runtime suggests continuing this workflow as new.
226
+ *
227
+ * Use this to decide whether to `continueAsNew` before long waits or at loop boundaries.
228
+ * Prefer returning the `continueAsNew(...)` call immediately when this becomes `true`.
229
+ *
230
+ * @see {@link https://docs.temporal.io/develop/typescript/continue-as-new#how-to-test}
231
+ *
232
+ * @returns True if a continue-as-new is suggested for the current run; otherwise false.
233
+ */
234
+ isContinueAsNewSuggested: () => boolean
235
+ }
236
+ };
183
237
 
184
238
  /**
185
- * Creates a workflow orchestrator with defined schema for input only.
186
- *
187
- * @param {object} options - Workflow options
188
- * @param {string} options.name - Unique workflow name
189
- * @param {string} [options.description] - Description of the workflow
190
- * @param {z.ZodType} options.inputSchema - Zod schema for workflow input
191
- * @param {function} options.fn - Workflow logic: `(input: z.infer<InputSchema>) => Promise<void>`
192
- * @param {Options} [options.options] - Activity retry options
193
- * @returns {function} Callable workflow function: `(input: z.infer<InputSchema>) => Promise<void>`
239
+ * The handler function of a workflow.
240
+ *
241
+ * @param input - The workflow input; it matches the schema defined by `inputSchema`.
242
+ * @param context - A context object with tools and information.
243
+ *
244
+ * @returns A value matching the schema defined by `outputSchema`.
194
245
  */
195
- export function workflow<
196
- InputSchema extends AnyZodSchema
197
- >( options : {
198
- name: string,
199
- description?: string,
200
- inputSchema: InputSchema,
201
- fn: ( input: z.infer<InputSchema> ) => Promise<void>,
202
- options?: Options
203
- } ): ( input: z.infer<InputSchema>, extra?: WorkflowCallConfig ) => Promise<void>;
246
+ export type WorkflowFunction<
247
+ InputSchema extends AnyZodSchema | undefined = undefined,
248
+ OutputSchema extends AnyZodSchema | undefined = undefined
249
+ > = InputSchema extends AnyZodSchema ?
250
+ ( input: z.infer<InputSchema>, context: WorkflowContext<InputSchema, OutputSchema> ) =>
251
+ Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void> :
252
+ ( input?: undefined | null, context: WorkflowContext<InputSchema, OutputSchema> ) =>
253
+ Promise<OutputSchema extends AnyZodSchema ? z.infer<OutputSchema> : void>;
204
254
 
205
255
  /**
206
- * Creates a workflow orchestrator with defined schema for output only.
207
- *
208
- * @param {object} options - Workflow options
209
- * @param {string} options.name - Unique workflow name
210
- * @param {string} [options.description] - Description of the workflow
211
- * @param {z.ZodType} options.outputSchema - Zod schema for workflow output
212
- * @param {function} options.fn - Workflow logic: `() => Promise<z.infer<OutputSchema>>`
213
- * @param {Options} [options.options] - Activity retry options
214
- * @returns {function} Callable workflow function: `() => Promise<z.infer<OutputSchema>>`
256
+ * A wrapper around the user defined `fn` handler function.
257
+ *
258
+ * It accepts the same input and returns the same value, calling the user function inside.
259
+ *
260
+ * The second argument is a WorkflowInvocationConfiguration object, allowing workflows configuration overwrite.
261
+ *
262
+ * It adds input and output validation based on the `inputSchema`, `outputSchema`.
263
+ *
264
+ * @param input - The workflow input; it matches the schema defined by `inputSchema`.
265
+ * @param config - Additional configuration for the invocation.
266
+ * @returns A value matching the schema defined by `outputSchema`.
215
267
  */
216
- export function workflow<
217
- OutputSchema extends AnyZodSchema
218
- >( options : {
219
- name: string,
220
- description?: string,
221
- outputSchema: OutputSchema,
222
- fn: () => Promise<z.infer<OutputSchema>>,
223
- options?: Options
224
- } ): ( input?: undefined | null, extra?: WorkflowCallConfig ) => Promise<z.infer<OutputSchema>>;
268
+ export type WorkflowFunctionWrapper<WorkflowFunction> =
269
+ [Parameters<WorkflowFunction>[0]] extends [undefined | null] ?
270
+ ( input?: undefined | null, config?: WorkflowInvocationConfiguration ) => ReturnType<WorkflowFunction> :
271
+ ( input: Parameters<WorkflowFunction>[0], config?: WorkflowInvocationConfiguration ) => ReturnType<WorkflowFunction>;
225
272
 
226
273
  /**
227
- * Creates a workflow orchestrator without defined schemas.
228
- *
229
- * @param {object} options - Workflow options
230
- * @param {string} options.name - Unique workflow name
231
- * @param {string} [options.description] - Description of the workflow
232
- * @param {function} options.fn - Workflow logic: `() => Promise<void>`
233
- * @param {Options} [options.options] - Activity retry options
234
- * @returns {function} Callable workflow function: `() => Promise<void>`
274
+ * Creates a workflow.
275
+ *
276
+ * A workflow is an orchestration of one or more steps. It is translated to a Temporal Workflow.
277
+ *
278
+ * The workflow logic is defined in the `fn` handler function.
279
+ *
280
+ * The schema of the input that the function receives as the first argument is defined by `inputSchema`.
281
+ *
282
+ * The output of the `fn` handler must match `outputSchema`; otherwise, a validation error is raised.
283
+ *
284
+ * @remarks
285
+ * - Workflows should respect the same limitations as Temporal workflows.
286
+ * - Workflows can invoke steps or evaluators and cannot perform I/O directly.
287
+ * - The workflow `name` needs to be unique across all workflows in the project.
288
+ *
289
+ * @example
290
+ * ```
291
+ * import { step } from './my_steps.ts';
292
+ *
293
+ * workflow( {
294
+ * name: 'main',
295
+ * description: 'A generic workflow',
296
+ * inputSchema: z.object( {
297
+ * value: z.number()
298
+ * } ),
299
+ * outputSchema: z.string(),
300
+ * fn: async input => {
301
+ * const result = await step( input.value );
302
+ * return result as string;
303
+ * }
304
+ * } )
305
+ * ```
306
+ *
307
+ * @example Workflow without outputSchema
308
+ * ```
309
+ * import { step } from './my_steps.ts';
310
+ *
311
+ * workflow( {
312
+ * name: 'main',
313
+ * description: 'A generic workflow',
314
+ * inputSchema: z.object( {
315
+ * value: z.number()
316
+ * } ),
317
+ * fn: async input => {
318
+ * await step( input.value );
319
+ * }
320
+ * } )
321
+ * ```
322
+ *
323
+ * @example Workflow without inputSchema
324
+ * ```
325
+ * import { step } from './my_steps.ts';
326
+ *
327
+ * workflow( {
328
+ * name: 'main',
329
+ * description: 'A generic workflow',
330
+ * outputSchema: z.string(),
331
+ * fn: async () => {
332
+ * const result = await step();
333
+ * return result as string;
334
+ * }
335
+ * } )
336
+ * ```
337
+ *
338
+ * @example Workflow without inputSchema and outputSchema
339
+ * ```
340
+ * import { step } from './my_steps.ts';
341
+ *
342
+ * workflow( {
343
+ * name: 'main',
344
+ * description: 'A generic workflow',
345
+ * fn: async () => {
346
+ * await step();
347
+ * }
348
+ * } )
349
+ * ```
350
+ *
351
+ * @example Using continueAsNew
352
+ * The function `continueAsNew` (same as Temporal) can be used to create a new workflow with the same ID and pass different input.
353
+ *
354
+ * ```
355
+ * import { step } from './my_steps.ts';
356
+ *
357
+ * workflow( {
358
+ * name: 'main',
359
+ * description: 'A generic workflow',
360
+ * inputSchema: z.object( {
361
+ * value: z.number()
362
+ * } ),
363
+ * outputSchema: z.string(),
364
+ * fn: async ( input, context ) => {
365
+ * const result = await step( input.value );
366
+ * if ( context.control.isContinueAsNewSuggested() ) {
367
+ * return context.control.continueAsNew( input );
368
+ * }
369
+ *
370
+ * return result as string;
371
+ * }
372
+ * } )
373
+ * ```
374
+ *
375
+ * @param params - Workflow parameters
376
+ * @param params.name - Human-readable workflow name (must start with a letter or underscore, followed by letters, numbers, or underscores).
377
+ * @param params.description - Description of the workflow
378
+ * @param params.inputSchema - Zod schema for workflow input
379
+ * @param params.outputSchema - Zod schema for workflow output
380
+ * @param params.fn - A function containing the workflow code
381
+ * @param params.options - Temporal Activity options
382
+ * @returns The same handler function set at `fn` with a different signature
235
383
  */
236
- export function workflow( options : {
237
- name: string,
238
- description?: string,
239
- fn: () => Promise<void>,
240
- options?: Options
241
- } ): ( input?: undefined | null, extra?: WorkflowCallConfig ) => Promise<void>;
384
+ export declare function workflow<
385
+ InputSchema extends AnyZodSchema | undefined = undefined,
386
+ OutputSchema extends AnyZodSchema | undefined = undefined
387
+ >( params: {
388
+ name: string;
389
+ description?: string;
390
+ inputSchema?: InputSchema;
391
+ outputSchema?: OutputSchema;
392
+ fn: WorkflowFunction<InputSchema, OutputSchema>;
393
+ options?: TemporalActivityOptions;
394
+ } ): WorkflowFunctionWrapper<WorkflowFunction<InputSchema, OutputSchema>>;
242
395
 
243
396
  /*
244
397
  ╭───────────────────╮
@@ -248,31 +401,32 @@ export function workflow( options : {
248
401
  */
249
402
 
250
403
  /**
251
- * Generic EvaluationResult class, represents the result of an evaluation
404
+ * Represents the result of an evaluation.
405
+ *
406
+ * Generic base class; evaluators must return an instance of an EvaluationResult subclass.
252
407
  */
253
- class EvaluationResult {
408
+ export class EvaluationResult {
254
409
  /**
255
410
  * @constructor
256
- * @param {object} args
257
- * @param {any} args.value - The value of the evaluation
258
- * @param {number} args.confidence - The confidence on the evaluation
259
- * @param {string} [args.reasoning] - The reasoning behind the result
411
+ * @param args
412
+ * @param args.value - The value of the evaluation
413
+ * @param args.confidence - The confidence in the evaluation
414
+ * @param args.reasoning - The reasoning behind the result
260
415
  */
261
416
  constructor( args: { value: any; confidence: number; reasoning?: string } ); // eslint-disable-line @typescript-eslint/no-explicit-any
262
417
 
263
418
  /**
264
- * @returns {any} The evaluation result value
419
+ * @returns The evaluation result value
265
420
  */
266
-
267
421
  get value(): any; // eslint-disable-line @typescript-eslint/no-explicit-any
268
422
 
269
423
  /**
270
- * @returns {number} The evaluation result confidence
424
+ * @returns The evaluation result confidence
271
425
  */
272
426
  get confidence(): number;
273
427
 
274
428
  /**
275
- * @returns {string} The evaluation result reasoning
429
+ * @returns The evaluation result reasoning
276
430
  */
277
431
  get reasoning(): string;
278
432
  }
@@ -284,15 +438,15 @@ class EvaluationResult {
284
438
  export class EvaluationStringResult extends EvaluationResult {
285
439
  /**
286
440
  * @constructor
287
- * @param {object} args
288
- * @param {string} args.value - The value of the evaluation
289
- * @param {number} args.confidence - The confidence on the evaluation
290
- * @param {string} [args.reasoning] - The reasoning behind the result
441
+ * @param args
442
+ * @param args.value - The value of the evaluation
443
+ * @param args.confidence - The confidence on the evaluation
444
+ * @param args.reasoning - The reasoning behind the result
291
445
  */
292
446
  constructor( args: { value: string; confidence: number; reasoning?: string } );
293
447
 
294
448
  /**
295
- * @returns {string} The evaluation result value
449
+ * @returns The evaluation result value
296
450
  */
297
451
  get value(): string;
298
452
  }
@@ -304,15 +458,15 @@ export class EvaluationStringResult extends EvaluationResult {
304
458
  export class EvaluationNumberResult extends EvaluationResult {
305
459
  /**
306
460
  * @constructor
307
- * @param {object} args
308
- * @param {number} args.value - The value of the evaluation
309
- * @param {number} args.confidence - The confidence on the evaluation
310
- * @param {string} [args.reasoning] - The reasoning behind the result
461
+ * @param args
462
+ * @param args.value - The value of the evaluation
463
+ * @param args.confidence - The confidence on the evaluation
464
+ * @param args.reasoning - The reasoning behind the result
311
465
  */
312
466
  constructor( args: { value: number; confidence: number; reasoning?: string } );
313
467
 
314
468
  /**
315
- * @returns {number} The evaluation result value
469
+ * @returns The evaluation result value
316
470
  */
317
471
  get value(): number;
318
472
  }
@@ -324,71 +478,72 @@ export class EvaluationNumberResult extends EvaluationResult {
324
478
  export class EvaluationBooleanResult extends EvaluationResult {
325
479
  /**
326
480
  * @constructor
327
- * @param {object} args
328
- * @param {boolean} args.value - The value of the evaluation
329
- * @param {number} args.confidence - The confidence on the evaluation
330
- * @param {string} [args.reasoning] - The reasoning behind the result
481
+ * @param args
482
+ * @param args.value - The value of the evaluation
483
+ * @param args.confidence - The confidence on the evaluation
484
+ * @param args.reasoning - The reasoning behind the result
331
485
  */
332
486
  constructor( args: { value: boolean; confidence: number; reasoning?: string } );
333
487
 
334
488
  /**
335
- * @returns {boolean} The evaluation result value
489
+ * @returns The evaluation result value
336
490
  */
337
491
  get value(): boolean;
338
492
  }
339
493
 
340
- /*
341
- * There are 2 overloads of the "evaluator" function:
342
- * - with fn receiving input;
343
- * - with fn receiving void;
494
+ /**
495
+ * The handler function of an evaluator.
496
+ *
497
+ * @param input - The evaluator input; it matches the schema defined by `inputSchema`.
498
+ *
499
+ * @returns The result of the evaluation.
344
500
  */
501
+ export type EvaluatorFunction<
502
+ InputSchema extends AnyZodSchema | undefined = undefined,
503
+ Result extends EvaluationResult
504
+ > = InputSchema extends AnyZodSchema ?
505
+ ( input: z.infer<InputSchema> ) => Promise<Result> :
506
+ () => Promise<Result>;
345
507
 
346
508
  /**
347
- * Creates workflow evaluation of work defined schema for input.
348
- *
349
- * @param {object} options - Evaluator options
350
- * @param {string} options.name - Human-readable evaluator name (only letters, numbers and "_")
351
- * @param {string} [options.description] - Description of the evaluator
352
- * @param {z.ZodType} options.inputSchema - Zod schema for the fn input
353
- * @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
354
- * @param {Options} [options.options] - Activity retry options
355
- * @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
509
+ * A wrapper around the user defined `fn` handler function.
510
+ *
511
+ * It has the same signature and returns the same value, calling the user function inside.
512
+ *
513
+ * It adds input validation based on the `inputSchema`.
356
514
  */
357
- export async function evaluator<
358
- InputSchema extends AnyZodSchema,
359
- Result extends EvaluationResult
360
- >( options: {
361
- name: string;
362
- description?: string;
363
- inputSchema: InputSchema;
364
- fn: ( input: z.infer<InputSchema> ) => Promise<Result>;
365
- options?: Options;
366
- } ): ( input: z.infer<InputSchema> ) => Promise<Result>;
515
+ export type EvaluatorFunctionWrapper<EvaluatorFunction> =
516
+ Parameters<EvaluatorFunction> extends [infer Input] ?
517
+ ( input: Input ) => ReturnType<EvaluatorFunction> :
518
+ () => ReturnType<EvaluatorFunction>;
367
519
 
368
520
  /**
369
- * Creates workflow evaluation without a defined input schema.
370
- *
371
- * @param {object} options - Evaluator options
372
- * @param {string} options.name - Human-readable evaluator name (only letters, numbers and "_")
373
- * @param {string} [options.description] - Description of the evaluator
374
- * @param {z.ZodType} options.inputSchema - Zod schema for the fn input
375
- * @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
376
- * @param {Options} [options.options] - Activity retry options
377
- * @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
521
+ * Creates an evaluation function. It is similar to a step, but must return an EvaluationResult.
522
+ *
523
+ * It is translated to a Temporal Activity.
524
+ *
525
+ * @param params - Evaluator parameters
526
+ * @param params.name - Human-readable evaluator name (must start with a letter or underscore, followed by letters, numbers, or underscores)
527
+ * @param params.description - Description of the evaluator
528
+ * @param params.inputSchema - Zod schema for the `fn` input
529
+ * @param params.fn - A function containing the evaluator code
530
+ * @param params.options - Temporal Activity options
531
+ * @returns A wrapper function around the `fn` function
378
532
  */
379
- export async function evaluator<
533
+ export declare function evaluator<
380
534
  InputSchema extends AnyZodSchema,
381
535
  Result extends EvaluationResult
382
- >( options: {
536
+ >( params: {
383
537
  name: string;
384
538
  description?: string;
385
- fn: ( input: z.infer<InputSchema> ) => Promise<Result>;
386
- options?: Options;
387
- } ): ( input: z.infer<InputSchema> ) => Promise<Result>;
539
+ inputSchema: InputSchema;
540
+ fn: EvaluatorFunction<InputSchema, Result>;
541
+ options?: TemporalActivityOptions;
542
+ } ): EvaluatorFunctionWrapper<EvaluatorFunction<InputSchema, Result>>;
388
543
 
389
544
  /*
390
545
  ╭───────────╮
391
- │ O T H E R │╮
546
+ T O O L S │╮
392
547
  ╰───────────╯│
393
548
  ╰───────────╯
394
549
  */
@@ -399,23 +554,32 @@ export async function evaluator<
399
554
  * Sends a request via an activity; the workflow will await a corresponding
400
555
  * resume signal to continue and return the response payload.
401
556
  *
402
- * @param {object} options - Webhook request options
403
- * @param {string} options.url - Webhook request url (POST)
404
- * @param {object} [options.payload] - Webhook request payload
405
- * @returns {Promise<object>} Resolves with the response payload when resumed
557
+ * @param params - Webhook request parameters
558
+ * @param params.url - Webhook request URL (POST)
559
+ * @param params.payload - Webhook request payload
560
+ * @returns Resolves with the response payload when resumed
406
561
  */
407
- export function createWebhook( options: { url: string; payload?: object } ): Promise<object>;
562
+ export declare function createWebhook( params: { url: string; payload?: object } ): Promise<object>;
563
+
564
+ /*
565
+ ╭─────────────╮
566
+ │ E R R O R S │╮
567
+ ╰─────────────╯│
568
+ ╰─────────────╯
569
+ */
408
570
 
409
571
  /**
410
572
  * Error indicating a non-recoverable failure.
411
573
  *
412
- * Use for failures that should not be retried by the workflow runtime.
574
+ * Throw this error to end the workflow execution altogether without retries.
413
575
  */
414
576
  export class FatalError extends Error {}
415
577
 
416
578
  /**
417
579
  * Error indicating invalid input or schema validation issues.
418
580
  *
419
- * Use for problems detected during input validation or contract checks.
581
+ * This error is thrown when there are validation errors, either in the input or output, for steps, evaluators, and workflows.
582
+ *
583
+ * It will end the workflow execution without retries.
420
584
  */
421
585
  export class ValidationError extends Error {}
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ import { step } from './interface/step.js';
3
3
  import { workflow } from './interface/workflow.js';
4
4
  import { createWebhook } from './interface/webhook.js';
5
5
  import { FatalError, ValidationError } from './errors.js';
6
+ export { continueAsNew } from '@temporalio/workflow';
6
7
  import { z } from 'zod';
7
8
 
8
9
  export {
@@ -1,5 +1,5 @@
1
1
  // THIS RUNS IN THE TEMPORAL'S SANDBOX ENVIRONMENT
2
- import { proxyActivities, inWorkflowContext, executeChild, workflowInfo, uuid4, ParentClosePolicy } from '@temporalio/workflow';
2
+ import { proxyActivities, inWorkflowContext, executeChild, workflowInfo, uuid4, ParentClosePolicy, continueAsNew } from '@temporalio/workflow';
3
3
  import { validateWorkflow } from './validations/static.js';
4
4
  import { validateWithSchema } from './validations/runtime.js';
5
5
  import { SHARED_STEP_PREFIX, ACTIVITY_GET_TRACE_DESTINATIONS } from '#consts';
@@ -35,12 +35,22 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
35
35
 
36
36
  const { workflowId, memo, startTime } = workflowInfo();
37
37
 
38
+ /* Context Object definition
39
+ - Control namespace: This object adds functions to interact with Temporal flow mechanisms
40
+ */
41
+ const context = {
42
+ control: {
43
+ isContinueAsNewSuggested: () => workflowInfo().continueAsNewSuggested,
44
+ continueAsNew
45
+ }
46
+ };
47
+
38
48
  // Root workflows will not have the execution context yet, since it is set here.
39
49
  const isRoot = !memo.executionContext;
40
50
 
41
- // Create the execution context object or preserve if it already exists:
42
- // It will always contains the information about the root workflow
43
- // It will be used to as context for tracing (connecting events)
51
+ /* Creates the execution context object or preserve if it already exists:
52
+ It will always contain the information about the root workflow
53
+ It will be used to as context for tracing (connecting events) */
44
54
  const executionContext = memo.executionContext ?? {
45
55
  workflowId,
46
56
  workflowName: name,
@@ -83,7 +93,7 @@ export function workflow( { name, description, inputSchema, outputSchema, fn, op
83
93
  ...( extra?.options && { activityOptions: mergeActivityOptions( activityOptions, extra.options ) } )
84
94
  }
85
95
  } )
86
- }, input );
96
+ }, input, context );
87
97
 
88
98
  validateWithSchema( outputSchema, output, `Workflow ${name} output` );
89
99
 
@@ -4,6 +4,7 @@ import { serializeError } from './tools/utils.js';
4
4
  import { isStringboolTrue } from '#utils';
5
5
  import * as localProcessor from './processors/local/index.js';
6
6
  import * as s3Processor from './processors/s3/index.js';
7
+ import { ComponentType } from '#consts';
7
8
 
8
9
  const traceBus = new EventEmitter();
9
10
  const processors = [
@@ -49,11 +50,15 @@ const serializeDetails = details => details instanceof Error ? serializeError( d
49
50
  * @param {object} fields - All the trace fields
50
51
  * @returns {void}
51
52
  */
52
- export const addEventPhase = ( phase, { kind, name, id, parentId, details, executionContext } ) =>
53
- traceBus.emit( 'entry', {
54
- executionContext,
55
- entry: { kind, phase, name, id, parentId, phase, timestamp: Date.now(), details: serializeDetails( details ) }
56
- } );
53
+ export const addEventPhase = ( phase, { kind, name, id, parentId, details, executionContext } ) => {
54
+ // Ignores internal steps in the actual trace files
55
+ if ( kind !== ComponentType.INTERNAL_STEP ) {
56
+ traceBus.emit( 'entry', {
57
+ executionContext,
58
+ entry: { kind, phase, name, id, parentId, phase, timestamp: Date.now(), details: serializeDetails( details ) }
59
+ } );
60
+ }
61
+ };
57
62
 
58
63
  /**
59
64
  * Adds an Event Phase, complementing the options with parentId and executionContext from the async storage.
@@ -1,5 +1,5 @@
1
1
  // THIS RUNS IN THE TEMPORAL'S SANDBOX ENVIRONMENT
2
- import { workflowInfo, proxySinks, ApplicationFailure } from '@temporalio/workflow';
2
+ import { workflowInfo, proxySinks, ApplicationFailure, ContinueAsNew } from '@temporalio/workflow';
3
3
  import { memoToHeaders } from '../sandboxed_utils.js';
4
4
  import { mergeActivityOptions } from '#utils';
5
5
  // this is a dynamic generated file with activity configs overwrites
@@ -37,6 +37,13 @@ class WorkflowExecutionInterceptor {
37
37
  sinks.trace.addWorkflowEventEnd( output );
38
38
  return output;
39
39
  } catch ( error ) {
40
+ /* When the error is ContinueAsNew it represents the point where the actual workflow code was
41
+ delegated to another run. In this case the result in the traces will be the string below and
42
+ a new trace file will be generated */
43
+ if ( error instanceof ContinueAsNew ) {
44
+ sinks.trace.addWorkflowEventEnd( '<continued_as_new>' );
45
+ throw error;
46
+ }
40
47
  sinks.trace.addWorkflowEventError( error );
41
48
  throw new ApplicationFailure( error.message, error.constructor.name );
42
49
  }