@elsium-ai/workflows 0.3.0 → 0.4.1

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/dist/dag.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { DagWorkflowConfig } from './types';
2
+ import type { Workflow } from './workflow';
3
+ export declare function defineDagWorkflow(config: DagWorkflowConfig): Workflow;
4
+ //# sourceMappingURL=dag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dag.d.ts","sourceRoot":"","sources":["../src/dag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEX,iBAAiB,EAKjB,MAAM,SAAS,CAAA;AAChB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAkJ1C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,QAAQ,CA+BrE"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { step, executeStep } from './step';
2
2
  export { defineWorkflow, defineParallelWorkflow, defineBranchWorkflow } from './workflow';
3
3
  export type { Workflow, ParallelWorkflowConfig, BranchConfig } from './workflow';
4
- export type { StepConfig, StepContext, StepResult, StepStatus, RetryConfig, WorkflowConfig, WorkflowResult, WorkflowStatus, WorkflowRunOptions, } from './types';
4
+ export { defineDagWorkflow } from './dag';
5
+ export type { StepConfig, StepContext, StepResult, StepStatus, RetryConfig, WorkflowConfig, WorkflowResult, WorkflowStatus, WorkflowRunOptions, DagStepConfig, DagWorkflowConfig, } from './types';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAG1C,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACzF,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGhF,YAAY,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,kBAAkB,GAClB,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAG1C,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACzF,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAGzC,YAAY,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,iBAAiB,GACjB,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -372,10 +372,128 @@ function defineBranchWorkflow(name, branches, fallback) {
372
372
  }
373
373
  };
374
374
  }
375
+ // src/dag.ts
376
+ function buildDependencyMaps(steps) {
377
+ const stepMap = new Map(steps.map((s) => [s.name, s]));
378
+ const inDegree = new Map;
379
+ const dependents = new Map;
380
+ for (const step2 of steps) {
381
+ inDegree.set(step2.name, 0);
382
+ dependents.set(step2.name, []);
383
+ }
384
+ for (const step2 of steps) {
385
+ validateAndRegisterDeps(step2, stepMap, inDegree, dependents);
386
+ }
387
+ return { inDegree, dependents };
388
+ }
389
+ function validateAndRegisterDeps(step2, stepMap, inDegree, dependents) {
390
+ for (const dep of step2.dependsOn ?? []) {
391
+ if (!stepMap.has(dep)) {
392
+ throw new Error(`Step "${step2.name}" depends on unknown step "${dep}"`);
393
+ }
394
+ inDegree.set(step2.name, (inDegree.get(step2.name) ?? 0) + 1);
395
+ dependents.get(dep)?.push(step2.name);
396
+ }
397
+ }
398
+ function findNextWave(inDegree, resolved, steps) {
399
+ const wave = [];
400
+ for (const [name, degree] of inDegree) {
401
+ if (degree === 0 && !resolved.has(name)) {
402
+ wave.push(name);
403
+ }
404
+ }
405
+ if (wave.length === 0) {
406
+ const remaining = steps.filter((s) => !resolved.has(s.name)).map((s) => s.name);
407
+ throw new Error(`Cycle detected in DAG workflow. Remaining steps: ${remaining.join(", ")}`);
408
+ }
409
+ return wave;
410
+ }
411
+ function resolveWave(wave, resolved, inDegree, dependents) {
412
+ for (const name of wave) {
413
+ resolved.add(name);
414
+ for (const dep of dependents.get(name) ?? []) {
415
+ inDegree.set(dep, (inDegree.get(dep) ?? 0) - 1);
416
+ }
417
+ }
418
+ }
419
+ function topologicalSort(steps) {
420
+ const { inDegree, dependents } = buildDependencyMaps(steps);
421
+ const waves = [];
422
+ const resolved = new Set;
423
+ while (resolved.size < steps.length) {
424
+ const wave = findNextWave(inDegree, resolved, steps);
425
+ resolveWave(wave, resolved, inDegree, dependents);
426
+ waves.push(wave);
427
+ }
428
+ return waves;
429
+ }
430
+ function resolveStepInput(stepConfig, outputs, input) {
431
+ const deps = stepConfig.dependsOn ?? [];
432
+ return deps.length > 0 ? outputs[deps[0]] ?? input : input;
433
+ }
434
+ function executeWaveSteps(wave, stepMap, config, input, outputs, options) {
435
+ const wavePromises = wave.map((stepName) => stepMap.get(stepName)).filter((s) => s !== undefined).map((stepConfig) => {
436
+ const stepInput = resolveStepInput(stepConfig, outputs, input);
437
+ const context = {
438
+ workflowName: config.name,
439
+ stepIndex: config.steps.indexOf(stepConfig),
440
+ previousOutputs: { ...outputs },
441
+ signal: options?.signal
442
+ };
443
+ return executeStep(stepConfig, stepInput, context);
444
+ });
445
+ return Promise.all(wavePromises);
446
+ }
447
+ async function processWaveResults(waveResults, wave, stepResults, outputs, config) {
448
+ let failed = false;
449
+ for (let i = 0;i < waveResults.length; i++) {
450
+ const result = waveResults[i];
451
+ const stepName = wave[i];
452
+ stepResults.push(result);
453
+ if (result.status === "completed" && result.data !== undefined) {
454
+ outputs[stepName] = result.data;
455
+ }
456
+ await config.onStepComplete?.(result);
457
+ if (result.status === "failed") {
458
+ failed = true;
459
+ await config.onStepError?.(new Error(result.error ?? "Step failed"), stepName);
460
+ }
461
+ }
462
+ return failed;
463
+ }
464
+ function defineDagWorkflow(config) {
465
+ const stepMap = new Map(config.steps.map((s) => [s.name, s]));
466
+ return {
467
+ name: config.name,
468
+ async run(input, options) {
469
+ const startTime = performance.now();
470
+ const waves = topologicalSort(config.steps);
471
+ const stepResults = [];
472
+ const outputs = {};
473
+ let failed = false;
474
+ for (const wave of waves) {
475
+ const waveResults = await executeWaveSteps(wave, stepMap, config, input, outputs, options);
476
+ failed = await processWaveResults(waveResults, wave, stepResults, outputs, config);
477
+ if (failed)
478
+ break;
479
+ }
480
+ const workflowResult = {
481
+ name: config.name,
482
+ status: failed ? "failed" : "completed",
483
+ steps: stepResults,
484
+ totalDurationMs: Math.round(performance.now() - startTime),
485
+ outputs
486
+ };
487
+ await config.onComplete?.(workflowResult);
488
+ return workflowResult;
489
+ }
490
+ };
491
+ }
375
492
  export {
376
493
  step,
377
494
  executeStep,
378
495
  defineWorkflow,
379
496
  defineParallelWorkflow,
497
+ defineDagWorkflow,
380
498
  defineBranchWorkflow
381
499
  };
package/dist/types.d.ts CHANGED
@@ -47,4 +47,14 @@ export interface WorkflowResult {
47
47
  export interface WorkflowRunOptions {
48
48
  signal?: AbortSignal;
49
49
  }
50
+ export interface DagStepConfig<TInput = unknown, TOutput = unknown> extends StepConfig<TInput, TOutput> {
51
+ dependsOn?: string[];
52
+ }
53
+ export interface DagWorkflowConfig {
54
+ name: string;
55
+ steps: DagStepConfig[];
56
+ onStepComplete?: (result: StepResult) => void | Promise<void>;
57
+ onStepError?: (error: Error, stepName: string) => void | Promise<void>;
58
+ onComplete?: (result: WorkflowResult) => void | Promise<void>;
59
+ }
50
60
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAI5B,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEnF,MAAM,WAAW,UAAU,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAClE,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA;IAC5D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,MAAM,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CAClB;AAID,MAAM,WAAW,WAAW;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;CACvC;AAID,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;AAE3E,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7D;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elsium-ai/workflows",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Multi-step workflow pipelines and DAG execution for ElsiumAI",
5
5
  "license": "MIT",
6
6
  "author": "Eric Utrera <ebutrera9103@gmail.com>",
@@ -26,7 +26,7 @@
26
26
  "dev": "bun --watch src/index.ts"
27
27
  },
28
28
  "dependencies": {
29
- "@elsium-ai/core": "^0.3.0",
29
+ "@elsium-ai/core": "^0.4.1",
30
30
  "zod": "^3.24.0"
31
31
  },
32
32
  "devDependencies": {