@output.ai/core 0.3.0 → 0.3.2

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/README.md CHANGED
@@ -3,96 +3,9 @@
3
3
  Workflow orchestration and worker runtime for building durable LLM applications with Temporal.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@output.ai/core)](https://www.npmjs.com/package/@output.ai/core)
6
- [![Documentation](https://img.shields.io/badge/docs-docs.output.ai-blue)](https://docs.output.ai/packages/core)
7
-
8
- ## Installation
9
-
10
- ```bash
11
- npm install @output.ai/core
12
- ```
13
-
14
- ## Quick Start
15
-
16
- ```typescript
17
- // workflow.ts
18
- import { workflow, z } from '@output.ai/core';
19
- import { processData } from './steps.js';
20
-
21
- export default workflow({
22
- name: 'myWorkflow',
23
- inputSchema: z.object({ text: z.string() }),
24
- outputSchema: z.object({ result: z.string() }),
25
- fn: async (input) => {
26
- const result = await processData(input.text);
27
- return { result };
28
- }
29
- });
30
- ```
31
-
32
- ```typescript
33
- // steps.ts
34
- import { step, z } from '@output.ai/core';
35
-
36
- export const processData = step({
37
- name: 'processData',
38
- inputSchema: z.string(),
39
- outputSchema: z.string(),
40
- fn: async (text) => {
41
- return text.toUpperCase();
42
- }
43
- });
44
- ```
45
-
46
- ## Key Exports
47
-
48
- | Export | Description |
49
- |--------|-------------|
50
- | `workflow` | Define orchestration logic that coordinates steps |
51
- | `step` | Define reusable units of work that handle I/O |
52
- | `evaluator` | Define steps that return evaluation results |
53
- | `createWebhook` | Pause workflow execution until external input |
54
- | `z` | Zod schema library for input/output validation |
55
-
56
- ## File Structure
57
-
58
- Each workflow lives in its own directory:
59
-
60
- ```text
61
- src/workflows/
62
- └── my-workflow/
63
- ├── workflow.ts # Workflow definition
64
- ├── steps.ts # Step implementations
65
- ├── evaluators.ts # Evaluators (optional)
66
- ├── prompts/ # LLM prompt templates
67
- │ └── prompt@v1.prompt
68
- └── scenarios/ # Test scenarios
69
- └── test_input.json
70
- ```
71
-
72
- ## Environment Variables
73
-
74
- The worker reads these environment variables:
75
-
76
- | Variable | Description |
77
- |----------|-------------|
78
- | `TEMPORAL_ADDRESS` | Temporal backend address |
79
- | `TEMPORAL_NAMESPACE` | Temporal namespace name |
80
- | `TEMPORAL_API_KEY` | API key for remote Temporal (leave blank for local) |
81
- | `CATALOG_ID` | **Required.** Name of the local catalog (use your email) |
82
- | `API_AUTH_KEY` | API key for Framework API (blank for local, required for remote) |
83
- | `TRACE_LOCAL_ON` | Enable local trace saving (requires `REDIS_URL`) |
84
- | `TRACE_REMOTE_ON` | Enable remote trace saving (requires `REDIS_URL` and AWS secrets) |
85
- | `REDIS_URL` | Redis address (required when tracing is enabled) |
86
- | `TRACE_REMOTE_S3_BUCKET` | AWS S3 bucket for traces (required for remote tracing) |
87
- | `AWS_REGION` | AWS region matching the S3 bucket (required for remote tracing) |
88
- | `AWS_ACCESS_KEY_ID` | AWS key ID (required for remote tracing) |
89
- | `AWS_SECRET_ACCESS_KEY` | AWS secret key (required for remote tracing) |
90
6
 
91
7
  ## Documentation
8
+ - [README](https://docs.output.ai/packages/core)
9
+ - [API Reference](https://output-ai-reference-code-docs.onrender.com/modules/core_src.html)
92
10
 
93
- For comprehensive documentation, visit:
94
-
95
- - [Package Reference](https://docs.output.ai/packages/core)
96
- - [Workflows Guide](https://docs.output.ai/core/workflows)
97
- - [Steps Guide](https://docs.output.ai/core/steps)
98
- - [Getting Started](https://docs.output.ai/quickstart)
11
+ <!-- Internal Dev Note: The documentation for this package is found at docs/guides/packages/core.mdx -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@output.ai/core",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "The core module of the output framework",
5
5
  "type": "module",
6
6
  "exports": {
package/src/index.d.ts CHANGED
@@ -79,6 +79,15 @@ export type HttpMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
79
79
  */
80
80
  export type TemporalActivityOptions = Omit<ActivityOptions, 'versioningIntent' | 'taskQueue' | 'allowEagerDispatch'>;
81
81
 
82
+ /**
83
+ * Result of a single job executed by `executeInParallel`.
84
+ *
85
+ * @typeParam T - The return type of the job function
86
+ */
87
+ export type ParallelJobResult<T> =
88
+ | { ok: true; result: T; index: number } |
89
+ { ok: false; error: unknown; index: number };
90
+
82
91
  /*
83
92
  ╭─────────╮
84
93
  │ S T E P │╮
@@ -480,6 +489,81 @@ export declare function workflow<
480
489
  ╰───────────────────╯
481
490
  */
482
491
 
492
+ /**
493
+ * A single feedback for an EvaluationResult
494
+ */
495
+ export class EvaluationFeedback {
496
+ /**
497
+ * Issue found
498
+ */
499
+ issue: string;
500
+
501
+ /**
502
+ * Improvement suggestion
503
+ */
504
+ suggestion?: string;
505
+
506
+ /**
507
+ * Reference for the issue
508
+ */
509
+ reference?: string;
510
+
511
+ /**
512
+ * Issue priority
513
+ */
514
+ priority?: 'low' | 'medium' | 'high' | 'critical';
515
+
516
+ /**
517
+ * @constructor
518
+ * @param args
519
+ * @param args.issue
520
+ * @param args.suggestion
521
+ * @param args.reference
522
+ * @param args.priority
523
+ */
524
+ constructor( args: {
525
+ issue: string;
526
+ suggestion?: string;
527
+ reference?: string;
528
+ priority?: 'low' | 'medium' | 'high' | 'critical';
529
+ } );
530
+
531
+ /**
532
+ * @returns The zod schema for this class
533
+ */
534
+ static get schema(): z.ZodType;
535
+ }
536
+
537
+ /**
538
+ * Base constructor arguments for EvaluationResult classes
539
+ */
540
+ export type EvaluationResultArgs<TValue = any> = { // eslint-disable-line @typescript-eslint/no-explicit-any
541
+ /**
542
+ * The value of the evaluation
543
+ */
544
+ value: TValue;
545
+ /**
546
+ * The confidence in the evaluation
547
+ */
548
+ confidence: number;
549
+ /**
550
+ * The name of the evaluation
551
+ */
552
+ name?: string;
553
+ /**
554
+ * The reasoning behind the result
555
+ */
556
+ reasoning?: string;
557
+ /**
558
+ * Feedback for this evaluation
559
+ */
560
+ feedback?: EvaluationFeedback[];
561
+ /**
562
+ * Dimensions of this evaluation
563
+ */
564
+ dimensions?: Array<EvaluationStringResult | EvaluationNumberResult | EvaluationBooleanResult>;
565
+ };
566
+
483
567
  /**
484
568
  * Represents the result of an evaluation.
485
569
  *
@@ -487,33 +571,45 @@ export declare function workflow<
487
571
  */
488
572
  export class EvaluationResult {
489
573
  /**
490
- * @constructor
491
- * @param args
492
- * @param args.value - The value of the evaluation
493
- * @param args.confidence - The confidence in the evaluation
494
- * @param args.reasoning - The reasoning behind the result
574
+ * The name of the evaluation result
575
+ */
576
+ name?: string;
577
+
578
+ /**
579
+ * The evaluation result value
580
+ */
581
+ value: any; // eslint-disable-line @typescript-eslint/no-explicit-any
582
+
583
+ /**
584
+ * The evaluation result confidence
495
585
  */
496
- constructor( args: { value: any; confidence: number; reasoning?: string } ); // eslint-disable-line @typescript-eslint/no-explicit-any
586
+ confidence: number;
497
587
 
498
588
  /**
499
- * @returns The evaluation result value
589
+ * The evaluation result reasoning
500
590
  */
501
- get value(): any; // eslint-disable-line @typescript-eslint/no-explicit-any
591
+ reasoning?: string;
502
592
 
503
593
  /**
504
- * @returns The evaluation result confidence
594
+ * Feedback for this evaluation
505
595
  */
506
- get confidence(): number;
596
+ feedback: EvaluationFeedback[];
507
597
 
508
598
  /**
509
- * @returns The evaluation result reasoning
599
+ * Dimensions of this evaluation
510
600
  */
511
- get reasoning(): string;
601
+ dimensions: Array<EvaluationStringResult | EvaluationNumberResult | EvaluationBooleanResult>;
512
602
 
513
603
  /**
514
- * @returns A zod schema representing this class
604
+ * @constructor
605
+ * @param args
606
+ */
607
+ constructor( args: EvaluationResultArgs );
608
+
609
+ /**
610
+ * @returns The zod schema for this class
515
611
  */
516
- get schema(): string;
612
+ static get schema(): z.ZodType;
517
613
  }
518
614
 
519
615
  /**
@@ -524,16 +620,8 @@ export class EvaluationStringResult extends EvaluationResult {
524
620
  /**
525
621
  * @constructor
526
622
  * @param args
527
- * @param args.value - The value of the evaluation
528
- * @param args.confidence - The confidence on the evaluation
529
- * @param args.reasoning - The reasoning behind the result
530
623
  */
531
- constructor( args: { value: string; confidence: number; reasoning?: string } );
532
-
533
- /**
534
- * @returns The evaluation result value
535
- */
536
- get value(): string;
624
+ constructor( args: EvaluationResultArgs<string> );
537
625
  }
538
626
 
539
627
  /**
@@ -544,16 +632,8 @@ export class EvaluationNumberResult extends EvaluationResult {
544
632
  /**
545
633
  * @constructor
546
634
  * @param args
547
- * @param args.value - The value of the evaluation
548
- * @param args.confidence - The confidence on the evaluation
549
- * @param args.reasoning - The reasoning behind the result
550
- */
551
- constructor( args: { value: number; confidence: number; reasoning?: string } );
552
-
553
- /**
554
- * @returns The evaluation result value
555
635
  */
556
- get value(): number;
636
+ constructor( args: EvaluationResultArgs<number> );
557
637
  }
558
638
 
559
639
  /**
@@ -564,16 +644,8 @@ export class EvaluationBooleanResult extends EvaluationResult {
564
644
  /**
565
645
  * @constructor
566
646
  * @param args
567
- * @param args.value - The value of the evaluation
568
- * @param args.confidence - The confidence on the evaluation
569
- * @param args.reasoning - The reasoning behind the result
570
647
  */
571
- constructor( args: { value: boolean; confidence: number; reasoning?: string } );
572
-
573
- /**
574
- * @returns The evaluation result value
575
- */
576
- get value(): boolean;
648
+ constructor( args: EvaluationResultArgs<boolean> );
577
649
  }
578
650
 
579
651
  /**
@@ -717,6 +789,51 @@ export declare function sendHttpRequest( params: {
717
789
  headers?: Record<string, string>;
718
790
  } ): Promise<SerializedFetchResponse>;
719
791
 
792
+ /**
793
+ * Execute jobs in parallel with optional concurrency limit.
794
+ *
795
+ * Returns all job results (successes and failures) sorted by original job index.
796
+ * Each result contains `ok` (boolean), `index` (original position), and either
797
+ * `result` (on success) or `error` (on failure).
798
+ *
799
+ * Jobs must be wrapped in arrow functions—do not pass promises directly.
800
+ *
801
+ * @example
802
+ * ```ts
803
+ * const results = await executeInParallel( {
804
+ * jobs: [
805
+ * () => myStep( data1 ),
806
+ * () => myStep( data2 ),
807
+ * () => myStep( data3 )
808
+ * ],
809
+ * concurrency: 2
810
+ * } );
811
+ *
812
+ * // Handle the discriminated union (result only exists when ok is true)
813
+ * const successfulResults = results.filter( r => r.ok ).map( r => r.result );
814
+ *
815
+ * // Or handle each result individually
816
+ * for ( const r of results ) {
817
+ * if ( r.ok ) {
818
+ * console.log( `Job ${r.index} succeeded:`, r.result );
819
+ * } else {
820
+ * console.log( `Job ${r.index} failed:`, r.error );
821
+ * }
822
+ * }
823
+ * ```
824
+ *
825
+ * @param params - Parameters object
826
+ * @param params.jobs - Array of arrow functions returning step/activity calls (not promises directly)
827
+ * @param params.concurrency - Max concurrent jobs (default: Infinity)
828
+ * @param params.onJobCompleted - Optional callback invoked as each job completes (in completion order)
829
+ * @returns Array of results sorted by original job index
830
+ */
831
+ export declare function executeInParallel<T>( params: {
832
+ jobs: Array<() => Promise<T> | T>;
833
+ concurrency?: number;
834
+ onJobCompleted?: ( result: ParallelJobResult<T> ) => void;
835
+ } ): Promise<Array<ParallelJobResult<T>>>;
836
+
720
837
  /*
721
838
  ╭─────────────╮
722
839
  │ E R R O R S │╮
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { evaluator, EvaluationStringResult, EvaluationNumberResult, EvaluationBooleanResult } from './interface/evaluator.js';
2
2
  import { step } from './interface/step.js';
3
3
  import { workflow } from './interface/workflow.js';
4
+ import { executeInParallel } from './interface/workflow_utils.js';
4
5
  import { sendHttpRequest, sendPostRequestAndAwaitWebhook } from './interface/webhook.js';
5
6
  import { FatalError, ValidationError } from './errors.js';
6
7
  export { continueAsNew, sleep } from '@temporalio/workflow';
@@ -16,6 +17,7 @@ export {
16
17
  EvaluationStringResult,
17
18
  EvaluationBooleanResult,
18
19
  // webhook tools
20
+ executeInParallel,
19
21
  sendHttpRequest,
20
22
  sendPostRequestAndAwaitWebhook,
21
23
  // errors
@@ -11,56 +11,158 @@ import * as z from 'zod';
11
11
  class EvaluationResultValidationError extends ValidationError {};
12
12
 
13
13
  /**
14
- * Generic EvaluationResult class, represents the result
15
- * of an evaluation
14
+ * A single feedback for an EvaluationResult
15
+ */
16
+ export class EvaluationFeedback {
17
+
18
+ /**
19
+ * Issue found
20
+ * @type {string}
21
+ */
22
+ issue;
23
+
24
+ /**
25
+ * Improvement suggestion
26
+ * @type {string}
27
+ */
28
+ suggestion;
29
+
30
+ /**
31
+ * Reference for the issue
32
+ * @type {string}
33
+ */
34
+ reference;
35
+
36
+ /**
37
+ * Issue priority
38
+ * @type {'low' | 'medium' | 'high' | 'critical' | undefined}
39
+ */
40
+ priority;
41
+
42
+ /**
43
+ * The zod schema for this class
44
+ * @type {z.ZodType}
45
+ */
46
+ static get schema() {
47
+ return z.object( {
48
+ issue: z.string(),
49
+ suggestion: z.string().optional(),
50
+ reference: z.string().optional(),
51
+ priority: z.enum( [ 'low', 'medium', 'high', 'critical' ] ).optional()
52
+ } );
53
+ };
54
+
55
+ /**
56
+ * @constructor
57
+ * @param {object} args
58
+ * @param {string} args.issue
59
+ * @param {string} [args.suggestion]
60
+ * @param {string} [args.reference]
61
+ * @param {'low' | 'medium' | 'high' | 'critical'} [args.priority]
62
+ */
63
+ constructor( { issue, suggestion = undefined, reference = undefined, priority = undefined } ) {
64
+ const result = this.constructor.schema.safeParse( { issue, suggestion, reference, priority } );
65
+ if ( result.error ) {
66
+ throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
67
+ }
68
+ this.issue = issue;
69
+ this.suggestion = suggestion;
70
+ this.reference = reference;
71
+ this.priority = priority;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Generic EvaluationResult class, represents the result of an evaluation.
16
77
  */
17
78
  export class EvaluationResult {
18
79
 
19
80
  /**
20
- * Returns the evaluation result value
81
+ * The name of the evaluation result
82
+ * @type {string}
83
+ */
84
+ name;
85
+
86
+ /**
87
+ * The evaluation result value
21
88
  * @type {any}
22
89
  */
23
90
  value = null;
24
91
 
25
92
  /**
26
- * Returns the confidence value, between 0 and 1.
93
+ * The confidence value, between 0 and 1
27
94
  * @type {number}
28
95
  */
29
- confidence = undefined;
96
+ confidence;
30
97
 
31
98
  /**
32
- * Returns the reasoning value.
99
+ * The reasoning value
33
100
  * @type {string}
34
101
  */
35
- reasoning = undefined;
102
+ reasoning;
36
103
 
37
- static get valueSchema() {
38
- return z.any();
39
- };
104
+ /**
105
+ * Feedback for this evaluation
106
+ * @type {EvaluationFeedback[]}
107
+ */
108
+ feedback = [];
109
+
110
+ /**
111
+ * Dimensions of this evaluation
112
+ * @type {EvaluationResult[]}
113
+ */
114
+ dimensions = [];
40
115
 
116
+ /**
117
+ * The schema main field
118
+ * @type {z.ZodAny}
119
+ */
120
+ static valueSchema = z.any();
121
+
122
+ /**
123
+ * The zod schema for this class
124
+ * @type {z.ZodType}
125
+ */
41
126
  static get schema() {
42
- return z.object( {
127
+ const baseSchema = z.object( {
43
128
  value: this.valueSchema,
44
129
  confidence: z.number(),
45
- reasoning: z.string().optional()
130
+ reasoning: z.string().optional(),
131
+ name: z.string().optional(),
132
+ feedback: z.array( EvaluationFeedback.schema ).optional()
133
+ } );
134
+
135
+ // Adds dimension but keep it only one level deep
136
+ return baseSchema.extend( {
137
+ dimensions: z.array(
138
+ baseSchema.extend( {
139
+ value: z.union( [ z.string(), z.number(), z.boolean() ] )
140
+ } )
141
+ ).optional()
46
142
  } );
47
143
  };
48
144
 
49
145
  /**
50
146
  * @constructor
51
147
  * @param {object} args
52
- * @param {any} args.value - The value of the evaluation
53
- * @param {number} args.confidence - The confidence on the evaluation
54
- * @param {string} [args.reasoning] - The reasoning behind the result
148
+ * @param {any} args.value
149
+ * @param {number} args.confidence
150
+ * @param {string} [args.name]
151
+ * @param {EvaluationResult[]} [args.dimensions]
152
+ * @param {EvaluationFeedback[]} [args.feedback]
153
+ * @param {string} [args.reasoning]
55
154
  */
56
- constructor( args ) {
57
- const result = this.constructor.schema.safeParse( args );
155
+ constructor( { value, confidence, dimensions = [], feedback = [], name = undefined, reasoning = undefined } ) {
156
+ const result = this.constructor.schema.safeParse( { value, confidence, dimensions, feedback, name, reasoning } );
58
157
  if ( result.error ) {
59
158
  throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
60
159
  }
61
- this.value = args.value;
62
- this.confidence = args.confidence;
63
- this.reasoning = args.reasoning;
160
+ this.confidence = confidence;
161
+ this.value = value;
162
+ this.dimensions = dimensions;
163
+ this.feedback = feedback;
164
+ this.name = name;
165
+ this.reasoning = reasoning;
64
166
  }
65
167
  };
66
168
 
@@ -68,71 +170,51 @@ export class EvaluationResult {
68
170
  * An evaluation result that uses a string value
69
171
  * @extends EvaluationResult
70
172
  * @property {string} value - The evaluation result value
173
+ * @constructor
174
+ * @param {object} args
175
+ * @param {string} args.value - The value of the evaluation (must be a string)
176
+ * @see EvaluationResult#constructor for other parameters (confidence, reasoning)
71
177
  */
72
178
  export class EvaluationStringResult extends EvaluationResult {
73
- static get valueSchema() {
74
- return z.string();
75
- };
76
-
77
- /**
78
- * @constructor
79
- * @param {object} args
80
- * @param {string} args.value - The value of the evaluation
81
- * @param {number} args.confidence - The confidence on the evaluation
82
- * @param {string} [args.reasoning] - The reasoning behind the result
83
- */
84
- // eslint-disable-next-line no-useless-constructor
85
- constructor( args ) {
86
- super( args );
87
- }
179
+ static valueSchema = z.string();
88
180
  };
89
181
 
90
182
  /**
91
183
  * An evaluation result that uses a boolean value
92
184
  * @extends EvaluationResult
93
185
  * @property {boolean} value - The evaluation result value
186
+ * @constructor
187
+ * @param {object} args
188
+ * @param {boolean} args.value - The value of the evaluation (must be a boolean)
189
+ * @see EvaluationResult#constructor for other parameters (confidence, reasoning)
94
190
  */
95
191
  export class EvaluationBooleanResult extends EvaluationResult {
96
- static get valueSchema() {
97
- return z.boolean();
98
- };
99
-
100
- /**
101
- * @constructor
102
- * @param {object} args
103
- * @param {boolean} args.value - The value of the evaluation
104
- * @param {number} args.confidence - The confidence on the evaluation
105
- * @param {string} [args.reasoning] - The reasoning behind the result
106
- */
107
- // eslint-disable-next-line no-useless-constructor
108
- constructor( args ) {
109
- super( args );
110
- }
192
+ static valueSchema = z.boolean();
111
193
  };
112
194
 
113
195
  /**
114
196
  * An evaluation result that uses a number value
115
197
  * @extends EvaluationResult
116
198
  * @property {number} value - The evaluation result value
199
+ * @constructor
200
+ * @param {object} args
201
+ * @param {number} args.value - The value of the evaluation (must be a number)
202
+ * @see EvaluationResult#constructor for other parameters (confidence, reasoning)
117
203
  */
118
204
  export class EvaluationNumberResult extends EvaluationResult {
119
- static get valueSchema() {
120
- return z.number();
121
- };
122
-
123
- /**
124
- * @constructor
125
- * @param {object} args
126
- * @param {number} args.value - The value of the evaluation
127
- * @param {number} args.confidence - The confidence on the evaluation
128
- * @param {string} [args.reasoning] - The reasoning behind the result
129
- */
130
- // eslint-disable-next-line no-useless-constructor
131
- constructor( args ) {
132
- super( args );
133
- }
205
+ static valueSchema = z.number();
134
206
  };
135
207
 
208
+ /**
209
+ * Expose the function to create a new evaluator
210
+ * @param {object} opts
211
+ * @param {string} opts.name
212
+ * @param {string} opts.description
213
+ * @param {z.ZodType} opts.inputSchema
214
+ * @param {Function} opts.fn
215
+ * @param {object} opts.options
216
+ * @returns {Function}
217
+ */
136
218
  export function evaluator( { name, description, inputSchema, fn, options } ) {
137
219
  validateEvaluator( { name, description, inputSchema, fn, options } );
138
220