@output.ai/core 0.0.15 → 0.1.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/bin/worker.sh +1 -1
- package/package.json +17 -10
- package/src/configs.js +1 -6
- package/src/configs.spec.js +2 -50
- package/src/consts.js +6 -8
- package/src/index.d.ts +169 -7
- package/src/index.js +18 -1
- package/src/interface/evaluator.js +146 -0
- package/src/interface/step.js +4 -9
- package/src/interface/{schema_utils.js → validations/runtime.js} +0 -14
- package/src/interface/validations/runtime.spec.js +29 -0
- package/src/interface/validations/schema_utils.js +8 -0
- package/src/interface/validations/static.js +13 -1
- package/src/interface/validations/static.spec.js +29 -1
- package/src/interface/webhook.js +16 -4
- package/src/interface/workflow.js +32 -54
- package/src/internal_activities/index.js +16 -12
- package/src/tracing/index.d.ts +47 -0
- package/src/tracing/index.js +154 -0
- package/src/tracing/index.private.spec.js +84 -0
- package/src/tracing/index.public.spec.js +86 -0
- package/src/tracing/tracer_tree.js +83 -0
- package/src/tracing/tracer_tree.spec.js +115 -0
- package/src/tracing/utils.js +21 -0
- package/src/tracing/utils.spec.js +14 -0
- package/src/worker/catalog_workflow/catalog.js +19 -10
- package/src/worker/index.js +1 -5
- package/src/worker/interceptors/activity.js +28 -10
- package/src/worker/interceptors/workflow.js +19 -1
- package/src/worker/loader.js +6 -6
- package/src/worker/loader.spec.js +6 -9
- package/src/worker/sinks.js +56 -10
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.js +35 -4
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +12 -4
- package/src/worker/webpack_loaders/workflow_rewriter/index.mjs +5 -4
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.js +13 -4
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_fn_bodies.spec.js +16 -2
- package/src/worker/webpack_loaders/workflow_rewriter/tools.js +46 -13
- package/src/worker/webpack_loaders/workflow_rewriter/tools.spec.js +20 -2
- package/src/worker/tracer/index.js +0 -75
- package/src/worker/tracer/index.test.js +0 -103
- package/src/worker/tracer/tracer_tree.js +0 -84
- package/src/worker/tracer/tracer_tree.test.js +0 -115
- /package/src/{worker/async_storage.js → async_storage.js} +0 -0
- /package/src/interface/{schema_utils.spec.js → validations/schema_utils.spec.js} +0 -0
package/bin/worker.sh
CHANGED
|
@@ -18,7 +18,7 @@ fi
|
|
|
18
18
|
# Get the real script directory (should be node_modules/<pkg>/bin)
|
|
19
19
|
script_dir="$(cd "$(dirname "$real_script")" && pwd)"
|
|
20
20
|
|
|
21
|
-
# SDK dir is the parent (node_modules/
|
|
21
|
+
# SDK dir is the parent (node_modules/output-core)
|
|
22
22
|
sdk_dir="$(dirname "$script_dir")"
|
|
23
23
|
|
|
24
24
|
cd ${sdk_dir}
|
package/package.json
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@output.ai/core",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "The core module of the output framework",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./src/index.d.ts",
|
|
9
|
+
"import": "./src/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./tracing": {
|
|
12
|
+
"types": "./src/tracing/index.d.ts",
|
|
13
|
+
"import": "./src/tracing/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
8
16
|
"files": [
|
|
9
17
|
"./src",
|
|
10
18
|
"./bin"
|
|
11
19
|
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"worker": "node ./src/worker/index.js"
|
|
14
|
-
},
|
|
15
20
|
"bin": {
|
|
16
|
-
"
|
|
21
|
+
"output-worker": "./bin/worker.sh",
|
|
17
22
|
"outputai": "./bin/worker.sh"
|
|
18
23
|
},
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"url": "git+https://github.com/growthxai/flow-sdk"
|
|
24
|
+
"scripts": {
|
|
25
|
+
"worker": "node ./src/worker/index.js"
|
|
22
26
|
},
|
|
23
27
|
"dependencies": {
|
|
24
28
|
"@babel/generator": "7.28.3",
|
|
@@ -29,10 +33,13 @@
|
|
|
29
33
|
"@temporalio/workflow": "1.13.0",
|
|
30
34
|
"zod": "4.1.9"
|
|
31
35
|
},
|
|
36
|
+
"license": "UNLICENSED",
|
|
32
37
|
"imports": {
|
|
33
38
|
"#consts": "./src/consts.js",
|
|
34
39
|
"#configs": "./src/configs.js",
|
|
35
40
|
"#errors": "./src/errors.js",
|
|
41
|
+
"#tracing": "./src/tracing/index.js",
|
|
42
|
+
"#async_storage": "./src/async_storage.js",
|
|
36
43
|
"#internal_activities": "./src/internal_activities/index.js"
|
|
37
44
|
}
|
|
38
45
|
}
|
package/src/configs.js
CHANGED
|
@@ -7,8 +7,7 @@ const envVarSchema = z.object( {
|
|
|
7
7
|
TEMPORAL_NAMESPACE: z.string().optional().default( 'default' ),
|
|
8
8
|
TEMPORAL_API_KEY: z.string().optional(),
|
|
9
9
|
CATALOG_ID: z.string().regex( /^[a-z0-9_.@-]+$/i ),
|
|
10
|
-
API_AUTH_KEY: z.string().optional()
|
|
11
|
-
TRACING_ENABLED: z.stringbool().optional()
|
|
10
|
+
API_AUTH_KEY: z.string().optional()
|
|
12
11
|
} );
|
|
13
12
|
|
|
14
13
|
const { data: safeEnvVar, error } = envVarSchema.safeParse( process.env );
|
|
@@ -30,7 +29,3 @@ export const worker = {
|
|
|
30
29
|
export const api = {
|
|
31
30
|
authKey: safeEnvVar.API_AUTH_KEY
|
|
32
31
|
};
|
|
33
|
-
|
|
34
|
-
export const tracing = {
|
|
35
|
-
enabled: safeEnvVar.TRACING_ENABLED
|
|
36
|
-
};
|
package/src/configs.spec.js
CHANGED
|
@@ -181,38 +181,6 @@ describe( 'configs', () => {
|
|
|
181
181
|
const { api } = await import( './configs.js' );
|
|
182
182
|
expect( api.authKey ).toBeUndefined();
|
|
183
183
|
} );
|
|
184
|
-
|
|
185
|
-
it( 'should handle TRACING_ENABLED when true', async () => {
|
|
186
|
-
process.env = {
|
|
187
|
-
TEMPORAL_ADDRESS: 'http://localhost:7233',
|
|
188
|
-
CATALOG_ID: 'test-catalog',
|
|
189
|
-
TRACING_ENABLED: 'true'
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const { tracing } = await import( './configs.js' );
|
|
193
|
-
expect( tracing.enabled ).toBe( true );
|
|
194
|
-
} );
|
|
195
|
-
|
|
196
|
-
it( 'should handle TRACING_ENABLED when false', async () => {
|
|
197
|
-
process.env = {
|
|
198
|
-
TEMPORAL_ADDRESS: 'http://localhost:7233',
|
|
199
|
-
CATALOG_ID: 'test-catalog',
|
|
200
|
-
TRACING_ENABLED: 'false'
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
const { tracing } = await import( './configs.js' );
|
|
204
|
-
expect( tracing.enabled ).toBe( false );
|
|
205
|
-
} );
|
|
206
|
-
|
|
207
|
-
it( 'should handle missing TRACING_ENABLED', async () => {
|
|
208
|
-
process.env = {
|
|
209
|
-
TEMPORAL_ADDRESS: 'http://localhost:7233',
|
|
210
|
-
CATALOG_ID: 'test-catalog'
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const { tracing } = await import( './configs.js' );
|
|
214
|
-
expect( tracing.enabled ).toBeUndefined();
|
|
215
|
-
} );
|
|
216
184
|
} );
|
|
217
185
|
} );
|
|
218
186
|
|
|
@@ -253,20 +221,6 @@ describe( 'configs', () => {
|
|
|
253
221
|
} );
|
|
254
222
|
} );
|
|
255
223
|
|
|
256
|
-
it( 'should export tracing config', async () => {
|
|
257
|
-
process.env = {
|
|
258
|
-
TEMPORAL_ADDRESS: 'http://localhost:7233',
|
|
259
|
-
CATALOG_ID: 'test-catalog',
|
|
260
|
-
TRACING_ENABLED: 'true'
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const { tracing } = await import( './configs.js' );
|
|
264
|
-
|
|
265
|
-
expect( tracing ).toEqual( {
|
|
266
|
-
enabled: true
|
|
267
|
-
} );
|
|
268
|
-
} );
|
|
269
|
-
|
|
270
224
|
it( 'should have correct static worker config values', async () => {
|
|
271
225
|
process.env = {
|
|
272
226
|
TEMPORAL_ADDRESS: 'http://localhost:7233',
|
|
@@ -361,11 +315,10 @@ describe( 'configs', () => {
|
|
|
361
315
|
TEMPORAL_NAMESPACE: 'production',
|
|
362
316
|
TEMPORAL_API_KEY: 'prod-api-key-123',
|
|
363
317
|
CATALOG_ID: 'prod.catalog@v1',
|
|
364
|
-
API_AUTH_KEY: 'secure-auth-key'
|
|
365
|
-
TRACING_ENABLED: 'true'
|
|
318
|
+
API_AUTH_KEY: 'secure-auth-key'
|
|
366
319
|
};
|
|
367
320
|
|
|
368
|
-
const { worker, api
|
|
321
|
+
const { worker, api } = await import( './configs.js' );
|
|
369
322
|
|
|
370
323
|
expect( worker.address ).toBe( 'https://temporal.cloud.example.com' );
|
|
371
324
|
expect( worker.namespace ).toBe( 'production' );
|
|
@@ -373,7 +326,6 @@ describe( 'configs', () => {
|
|
|
373
326
|
expect( worker.catalogId ).toBe( 'prod.catalog@v1' );
|
|
374
327
|
expect( worker.taskQueue ).toBe( 'prod.catalog@v1' );
|
|
375
328
|
expect( api.authKey ).toBe( 'secure-auth-key' );
|
|
376
|
-
expect( tracing.enabled ).toBe( true );
|
|
377
329
|
} );
|
|
378
330
|
} );
|
|
379
331
|
} );
|
package/src/consts.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const ACTIVITY_SEND_WEBHOOK = '__internal#sendWebhook';
|
|
2
|
+
export const ACTIVITY_READ_TRACE_FILE = '__internal#readTraceFile';
|
|
3
3
|
export const METADATA_ACCESS_SYMBOL = Symbol( '__metadata' );
|
|
4
4
|
export const WORKFLOWS_INDEX_FILENAME = '__workflows_entrypoint.js';
|
|
5
|
-
export const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
STEP_START: 'step_start',
|
|
10
|
-
STEP_END: 'step_end'
|
|
5
|
+
export const ComponentType = {
|
|
6
|
+
EVALUATOR: 'evaluator',
|
|
7
|
+
INTERNAL_STEP: 'internal_step',
|
|
8
|
+
STEP: 'step'
|
|
11
9
|
};
|
package/src/index.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export { z } from 'zod';
|
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
20
|
type AnyZodSchema = z.ZodType<any, any, any>;
|
|
21
21
|
|
|
22
|
+
/*
|
|
23
|
+
╭─────────╮
|
|
24
|
+
│ S T E P │╮
|
|
25
|
+
╰─────────╯│
|
|
26
|
+
╰─────────╯
|
|
27
|
+
*/
|
|
28
|
+
|
|
22
29
|
/*
|
|
23
30
|
* There are 4 overloads of the "step" function:
|
|
24
31
|
* - with fn receiving input and returning output;
|
|
@@ -28,7 +35,7 @@ type AnyZodSchema = z.ZodType<any, any, any>;
|
|
|
28
35
|
*/
|
|
29
36
|
|
|
30
37
|
/**
|
|
31
|
-
* Creates logical unit of work
|
|
38
|
+
* Creates logical unit of work defined schema for both input and output.
|
|
32
39
|
*
|
|
33
40
|
* @param {object} options - Step options
|
|
34
41
|
* @param {string} options.name - Human-readable step name (only letters, numbers and "_")
|
|
@@ -50,7 +57,7 @@ export async function step<
|
|
|
50
57
|
} ): ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>;
|
|
51
58
|
|
|
52
59
|
/**
|
|
53
|
-
* Creates logical unit of work with
|
|
60
|
+
* Creates logical unit of work with defined schema for input only.
|
|
54
61
|
*
|
|
55
62
|
* @param {object} options - Step options
|
|
56
63
|
* @param {string} options.name - Human-readable step name (only letters, numbers and "_")
|
|
@@ -69,7 +76,7 @@ export async function step<
|
|
|
69
76
|
} ): ( input: z.infer<InputSchema> ) => Promise<void>;
|
|
70
77
|
|
|
71
78
|
/**
|
|
72
|
-
* Creates logical unit of work with
|
|
79
|
+
* Creates logical unit of work with defined schema for output only.
|
|
73
80
|
*
|
|
74
81
|
* @param {object} options - Step options
|
|
75
82
|
* @param {string} options.name - Human-readable step name (only letters, numbers and "_")
|
|
@@ -102,6 +109,12 @@ export async function step( options: {
|
|
|
102
109
|
fn: () => Promise<void>;
|
|
103
110
|
} ): () => Promise<void>;
|
|
104
111
|
|
|
112
|
+
/*
|
|
113
|
+
╭─────────────────╮
|
|
114
|
+
│ W O R K F L O W │╮
|
|
115
|
+
╰─────────────────╯│
|
|
116
|
+
╰─────────────────╯
|
|
117
|
+
*/
|
|
105
118
|
/*
|
|
106
119
|
* There are 4 overloads of the "workflow" function:
|
|
107
120
|
* - with fn receiving input and returning output;
|
|
@@ -111,7 +124,7 @@ export async function step( options: {
|
|
|
111
124
|
*/
|
|
112
125
|
|
|
113
126
|
/**
|
|
114
|
-
* Creates a workflow orchestrator
|
|
127
|
+
* Creates a workflow orchestrator defined schema for both input and output.
|
|
115
128
|
*
|
|
116
129
|
* @param {object} options - Workflow options
|
|
117
130
|
* @param {string} options.name - Unique workflow name
|
|
@@ -133,7 +146,7 @@ export function workflow<
|
|
|
133
146
|
} ): ( input: z.infer<InputSchema> ) => Promise<z.infer<OutputSchema>>;
|
|
134
147
|
|
|
135
148
|
/**
|
|
136
|
-
* Creates a workflow orchestrator with
|
|
149
|
+
* Creates a workflow orchestrator with defined schema for input only.
|
|
137
150
|
*
|
|
138
151
|
* @param {object} options - Workflow options
|
|
139
152
|
* @param {string} options.name - Unique workflow name
|
|
@@ -152,7 +165,7 @@ export function workflow<
|
|
|
152
165
|
} ): ( input: z.infer<InputSchema> ) => Promise<void>;
|
|
153
166
|
|
|
154
167
|
/**
|
|
155
|
-
* Creates a workflow orchestrator with
|
|
168
|
+
* Creates a workflow orchestrator with defined schema for output only.
|
|
156
169
|
*
|
|
157
170
|
* @param {object} options - Workflow options
|
|
158
171
|
* @param {string} options.name - Unique workflow name
|
|
@@ -171,7 +184,7 @@ export function workflow<
|
|
|
171
184
|
} ): () => Promise<z.infer<OutputSchema>>;
|
|
172
185
|
|
|
173
186
|
/**
|
|
174
|
-
* Creates a workflow orchestrator without schemas.
|
|
187
|
+
* Creates a workflow orchestrator without defined schemas.
|
|
175
188
|
*
|
|
176
189
|
* @param {object} options - Workflow options
|
|
177
190
|
* @param {string} options.name - Unique workflow name
|
|
@@ -185,6 +198,155 @@ export function workflow( options : {
|
|
|
185
198
|
fn: () => Promise<void>
|
|
186
199
|
} ): () => Promise<void>;
|
|
187
200
|
|
|
201
|
+
/*
|
|
202
|
+
╭───────────────────╮
|
|
203
|
+
│ E V A L U A T O R │╮
|
|
204
|
+
╰───────────────────╯│
|
|
205
|
+
╰───────────────────╯
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generic EvaluationResult class, represents the result of an evaluation
|
|
210
|
+
*/
|
|
211
|
+
class EvaluationResult {
|
|
212
|
+
/**
|
|
213
|
+
* @constructor
|
|
214
|
+
* @param {object} args
|
|
215
|
+
* @param {any} args.value - The value of the evaluation
|
|
216
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
217
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
218
|
+
*/
|
|
219
|
+
constructor( args: { value: any; confidence: number; reasoning?: string } ); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @returns {any} The evaluation result value
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
get value(): any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @returns {number} The evaluation result confidence
|
|
229
|
+
*/
|
|
230
|
+
get confidence(): number;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @returns {string} The evaluation result reasoning
|
|
234
|
+
*/
|
|
235
|
+
get reasoning(): string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* An evaluation result where the value is a string
|
|
240
|
+
* @extends EvaluationResult
|
|
241
|
+
*/
|
|
242
|
+
export class EvaluationStringResult extends EvaluationResult {
|
|
243
|
+
/**
|
|
244
|
+
* @constructor
|
|
245
|
+
* @param {object} args
|
|
246
|
+
* @param {string} args.value - The value of the evaluation
|
|
247
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
248
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
249
|
+
*/
|
|
250
|
+
constructor( args: { value: string; confidence: number; reasoning?: string } );
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @returns {string} The evaluation result value
|
|
254
|
+
*/
|
|
255
|
+
get value(): string;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* An evaluation result where the value is a number
|
|
260
|
+
* @extends EvaluationResult
|
|
261
|
+
*/
|
|
262
|
+
export class EvaluationNumberResult extends EvaluationResult {
|
|
263
|
+
/**
|
|
264
|
+
* @constructor
|
|
265
|
+
* @param {object} args
|
|
266
|
+
* @param {number} args.value - The value of the evaluation
|
|
267
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
268
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
269
|
+
*/
|
|
270
|
+
constructor( args: { value: number; confidence: number; reasoning?: string } );
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @returns {number} The evaluation result value
|
|
274
|
+
*/
|
|
275
|
+
get value(): number;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* An evaluation result where the value is a boolean
|
|
280
|
+
* @extends EvaluationResult
|
|
281
|
+
*/
|
|
282
|
+
export class EvaluationBooleanResult extends EvaluationResult {
|
|
283
|
+
/**
|
|
284
|
+
* @constructor
|
|
285
|
+
* @param {object} args
|
|
286
|
+
* @param {boolean} args.value - The value of the evaluation
|
|
287
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
288
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
289
|
+
*/
|
|
290
|
+
constructor( args: { value: boolean; confidence: number; reasoning?: string } );
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @returns {boolean} The evaluation result value
|
|
294
|
+
*/
|
|
295
|
+
get value(): boolean;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
* There are 2 overloads of the "evaluator" function:
|
|
300
|
+
* - with fn receiving input;
|
|
301
|
+
* - with fn receiving void;
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Creates workflow evaluation of work defined schema for input.
|
|
306
|
+
*
|
|
307
|
+
* @param {object} options - Evaluator options
|
|
308
|
+
* @param {string} options.name - Human-readable evaluator name (only letters, numbers and "_")
|
|
309
|
+
* @param {string} [options.description] - Description of the evaluator
|
|
310
|
+
* @param {z.ZodType} options.inputSchema - Zod schema for the fn input
|
|
311
|
+
* @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
|
|
312
|
+
* @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
|
|
313
|
+
*/
|
|
314
|
+
export async function evaluator<
|
|
315
|
+
InputSchema extends AnyZodSchema,
|
|
316
|
+
Result extends EvaluationResult
|
|
317
|
+
>( options: {
|
|
318
|
+
name: string;
|
|
319
|
+
description?: string;
|
|
320
|
+
inputSchema: InputSchema;
|
|
321
|
+
fn: ( input: z.infer<InputSchema> ) => Promise<Result>;
|
|
322
|
+
} ): ( input: z.infer<InputSchema> ) => Promise<Result>;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Creates workflow evaluation without a defined input schema.
|
|
326
|
+
*
|
|
327
|
+
* @param {object} options - Evaluator options
|
|
328
|
+
* @param {string} options.name - Human-readable evaluator name (only letters, numbers and "_")
|
|
329
|
+
* @param {string} [options.description] - Description of the evaluator
|
|
330
|
+
* @param {z.ZodType} options.inputSchema - Zod schema for the fn input
|
|
331
|
+
* @param {function} options.fn - The function logic: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
|
|
332
|
+
* @returns {function} Function with signature: `(input: z.infer<InputSchema>) => Promise<z.infer<OutputSchema>>`
|
|
333
|
+
*/
|
|
334
|
+
export async function evaluator<
|
|
335
|
+
InputSchema extends AnyZodSchema,
|
|
336
|
+
Result extends EvaluationResult
|
|
337
|
+
>( options: {
|
|
338
|
+
name: string;
|
|
339
|
+
description?: string;
|
|
340
|
+
fn: ( input: z.infer<InputSchema> ) => Promise<Result>;
|
|
341
|
+
} ): ( input: z.infer<InputSchema> ) => Promise<Result>;
|
|
342
|
+
|
|
343
|
+
/*
|
|
344
|
+
╭───────────╮
|
|
345
|
+
│ O T H E R │╮
|
|
346
|
+
╰───────────╯│
|
|
347
|
+
╰───────────╯
|
|
348
|
+
*/
|
|
349
|
+
|
|
188
350
|
/**
|
|
189
351
|
* Create a webhook call that pauses the workflow until resumed via signal.
|
|
190
352
|
*
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
import { evaluator, EvaluationStringResult, EvaluationNumberResult, EvaluationBooleanResult } from './interface/evaluator.js';
|
|
1
2
|
import { step } from './interface/step.js';
|
|
2
3
|
import { workflow } from './interface/workflow.js';
|
|
3
4
|
import { createWebhook } from './interface/webhook.js';
|
|
4
5
|
import { FatalError, ValidationError } from './errors.js';
|
|
5
6
|
import { z } from 'zod';
|
|
6
7
|
|
|
7
|
-
export {
|
|
8
|
+
export {
|
|
9
|
+
// base building blocks
|
|
10
|
+
evaluator,
|
|
11
|
+
step,
|
|
12
|
+
workflow,
|
|
13
|
+
// Evaluation results
|
|
14
|
+
EvaluationNumberResult,
|
|
15
|
+
EvaluationStringResult,
|
|
16
|
+
EvaluationBooleanResult,
|
|
17
|
+
// webhook tool
|
|
18
|
+
createWebhook,
|
|
19
|
+
// errors
|
|
20
|
+
FatalError,
|
|
21
|
+
ValidationError,
|
|
22
|
+
// zod
|
|
23
|
+
z
|
|
24
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { setMetadata } from './metadata.js';
|
|
2
|
+
import { validateEvaluator } from './validations/static.js';
|
|
3
|
+
import { validateWithSchema } from './validations/runtime.js';
|
|
4
|
+
import { ValidationError } from '#errors';
|
|
5
|
+
import { ComponentType } from '#consts';
|
|
6
|
+
import * as z from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Error for when EvaluationResult are invalid
|
|
10
|
+
*/
|
|
11
|
+
class EvaluationResultValidationError extends ValidationError {};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generic EvaluationResult class, represents the result
|
|
15
|
+
* of an evaluation
|
|
16
|
+
*/
|
|
17
|
+
export class EvaluationResult {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns the evaluation result value
|
|
21
|
+
* @type {any}
|
|
22
|
+
*/
|
|
23
|
+
value = null;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns the confidence value, between 0 and 1.
|
|
27
|
+
* @type {number}
|
|
28
|
+
*/
|
|
29
|
+
confidence = undefined;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the reasoning value.
|
|
33
|
+
* @type {string}
|
|
34
|
+
*/
|
|
35
|
+
reasoning = undefined;
|
|
36
|
+
|
|
37
|
+
static #schema = z.object( {
|
|
38
|
+
value: z.any(),
|
|
39
|
+
confidence: z.number(),
|
|
40
|
+
reasoning: z.string().optional()
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @constructor
|
|
45
|
+
* @param {object} args
|
|
46
|
+
* @param {any} args.value - The value of the evaluation
|
|
47
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
48
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
49
|
+
*/
|
|
50
|
+
constructor( args ) {
|
|
51
|
+
if ( !EvaluationResult.#schema.safeParse( args ) ) {
|
|
52
|
+
throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
|
|
53
|
+
}
|
|
54
|
+
this.value = args.value;
|
|
55
|
+
this.confidence = args.confidence;
|
|
56
|
+
this.reasoning = args.reasoning;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An evaluation result that uses a string value
|
|
62
|
+
* @extends EvaluationResult
|
|
63
|
+
* @property {string} value - The evaluation result value
|
|
64
|
+
*/
|
|
65
|
+
export class EvaluationStringResult extends EvaluationResult {
|
|
66
|
+
static #valueSchema = z.string();
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @constructor
|
|
70
|
+
* @param {object} args
|
|
71
|
+
* @param {string} args.value - The value of the evaluation
|
|
72
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
73
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
74
|
+
*/
|
|
75
|
+
constructor( args ) {
|
|
76
|
+
if ( !EvaluationStringResult.#valueSchema.safeParse( args.value ) ) {
|
|
77
|
+
throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
|
|
78
|
+
}
|
|
79
|
+
super( args );
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An evaluation result that uses a boolean value
|
|
85
|
+
* @extends EvaluationResult
|
|
86
|
+
* @property {boolean} value - The evaluation result value
|
|
87
|
+
*/
|
|
88
|
+
export class EvaluationBooleanResult extends EvaluationResult {
|
|
89
|
+
static #valueSchema = z.boolean();
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @constructor
|
|
93
|
+
* @param {object} args
|
|
94
|
+
* @param {boolean} args.value - The value of the evaluation
|
|
95
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
96
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
97
|
+
*/
|
|
98
|
+
constructor( args ) {
|
|
99
|
+
if ( !EvaluationBooleanResult.#valueSchema.safeParse( args.value ) ) {
|
|
100
|
+
throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
|
|
101
|
+
}
|
|
102
|
+
super( args );
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* An evaluation result that uses a number value
|
|
108
|
+
* @extends EvaluationResult
|
|
109
|
+
* @property {number} value - The evaluation result value
|
|
110
|
+
*/
|
|
111
|
+
export class EvaluationNumberResult extends EvaluationResult {
|
|
112
|
+
static #valueSchema = z.number();
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @constructor
|
|
116
|
+
* @param {object} args
|
|
117
|
+
* @param {number} args.value - The value of the evaluation
|
|
118
|
+
* @param {number} args.confidence - The confidence on the evaluation
|
|
119
|
+
* @param {string} [args.reasoning] - The reasoning behind the result
|
|
120
|
+
*/
|
|
121
|
+
constructor( args ) {
|
|
122
|
+
if ( !EvaluationNumberResult.#valueSchema.safeParse( args.value ) ) {
|
|
123
|
+
throw new EvaluationResultValidationError( z.prettifyError( result.error ) );
|
|
124
|
+
}
|
|
125
|
+
super( args );
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export function evaluator( { name, description, inputSchema, fn } ) {
|
|
130
|
+
validateEvaluator( { name, description, inputSchema, fn } );
|
|
131
|
+
|
|
132
|
+
const wrapper = async input => {
|
|
133
|
+
validateWithSchema( inputSchema, input, `Evaluator ${name} input` );
|
|
134
|
+
|
|
135
|
+
const output = await fn( input );
|
|
136
|
+
|
|
137
|
+
if ( !output instanceof EvaluationResult ) {
|
|
138
|
+
throw new ValidationError( 'Evaluators must return an EvaluationResult' );
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return output;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
setMetadata( wrapper, { name, description, inputSchema, type: ComponentType.EVALUATOR } );
|
|
145
|
+
return wrapper;
|
|
146
|
+
};
|
package/src/interface/step.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { setMetadata } from './metadata.js';
|
|
2
2
|
import { validateStep } from './validations/static.js';
|
|
3
|
-
import { validateWithSchema } from './
|
|
3
|
+
import { validateWithSchema } from './validations/runtime.js';
|
|
4
|
+
import { ComponentType } from '#consts';
|
|
4
5
|
|
|
5
6
|
export function step( { name, description, inputSchema, outputSchema, fn } ) {
|
|
6
|
-
validateStep( {
|
|
7
|
-
name,
|
|
8
|
-
description,
|
|
9
|
-
inputSchema,
|
|
10
|
-
outputSchema,
|
|
11
|
-
fn
|
|
12
|
-
} );
|
|
7
|
+
validateStep( { name, description, inputSchema, outputSchema, fn } );
|
|
13
8
|
|
|
14
9
|
const wrapper = async input => {
|
|
15
10
|
validateWithSchema( inputSchema, input, `Step ${name} input` );
|
|
@@ -21,6 +16,6 @@ export function step( { name, description, inputSchema, outputSchema, fn } ) {
|
|
|
21
16
|
return output;
|
|
22
17
|
};
|
|
23
18
|
|
|
24
|
-
setMetadata( wrapper, { name, description, inputSchema, outputSchema } );
|
|
19
|
+
setMetadata( wrapper, { name, description, inputSchema, outputSchema, type: ComponentType.STEP } );
|
|
25
20
|
return wrapper;
|
|
26
21
|
};
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import { ValidationError } from '#errors';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Detects if a schema is a Zod schema object
|
|
5
|
-
* @param {unknown} schema - The schema to check
|
|
6
|
-
* @returns {boolean} True if the schema is a Zod schema
|
|
7
|
-
*/
|
|
8
|
-
export function isZodSchema( schema ) {
|
|
9
|
-
return schema &&
|
|
10
|
-
typeof schema === 'object' &&
|
|
11
|
-
'_def' in schema &&
|
|
12
|
-
typeof schema.parse === 'function' &&
|
|
13
|
-
typeof schema.parseAsync === 'function';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
3
|
/**
|
|
17
4
|
* Validates data against a Zod schema using safeParse
|
|
18
5
|
* @param {unknown} schema - The Zod schema to validate against
|
|
@@ -31,4 +18,3 @@ export function validateWithSchema( schema, data, context ) {
|
|
|
31
18
|
throw new ValidationError( `${context} validation failed: ${result.error.message}` );
|
|
32
19
|
}
|
|
33
20
|
}
|
|
34
|
-
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { validateWithSchema } from './runtime.js';
|
|
4
|
+
import { ValidationError } from '#errors';
|
|
5
|
+
|
|
6
|
+
describe( 'runtime validations', () => {
|
|
7
|
+
describe( 'validateWithSchema', () => {
|
|
8
|
+
it( 'no-ops when schema is falsy', () => {
|
|
9
|
+
expect( () => validateWithSchema( undefined, { a: 1 }, 'X' ) ).not.toThrow();
|
|
10
|
+
expect( () => validateWithSchema( null, { a: 1 }, 'X' ) ).not.toThrow();
|
|
11
|
+
} );
|
|
12
|
+
|
|
13
|
+
it( 'passes on valid data', () => {
|
|
14
|
+
const schema = z.object( { a: z.string(), b: z.number().optional() } );
|
|
15
|
+
expect( () => validateWithSchema( schema, { a: 'ok' }, 'Test' ) ).not.toThrow();
|
|
16
|
+
} );
|
|
17
|
+
|
|
18
|
+
it( 'throws ValidationError on invalid data and prefixes context', () => {
|
|
19
|
+
const schema = z.object( { a: z.string() } );
|
|
20
|
+
const call = () => validateWithSchema( schema, { a: 1 }, 'MyCtx' );
|
|
21
|
+
expect( call ).toThrow( ValidationError );
|
|
22
|
+
try {
|
|
23
|
+
call();
|
|
24
|
+
} catch ( e ) {
|
|
25
|
+
expect( String( e.message ) ).toContain( 'MyCtx validation failed:' );
|
|
26
|
+
}
|
|
27
|
+
} );
|
|
28
|
+
} );
|
|
29
|
+
} );
|