@cadenza.io/core 3.9.0 → 3.9.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
@@ -7,12 +7,12 @@ Cadenza is an innovative framework that extends traditional orchestration with e
7
7
  The core package (@Cadenza.io/core) includes the foundational primitives for defining and executing graphs of tasks, managing contexts, handling signals, and bootstrapping executions. It's designed to be language-agnostic in model, with this TypeScript implementation serving as the reference.
8
8
 
9
9
  Cadenza's design philosophy emphasizes:
10
- - **Structured Freedom**: Explicit graphs for dependencies (orchestration) combined with signals for loose coupling (choreography).
11
- - **Meta-Layer Extension**: A self-reflective layer for monitoring, optimization, and auto-generation, enabling AI-driven self-development. Essentially extending the core, using the core.
10
+ - **Decentralized Adaptive Orchestration (DAO)**: Explicit graphs for dependencies (orchestration) combined with signals for loose coupling (choreography). This combination allows for flexible and dynamic workflows, while still maintaining the benefits of traditional orchestration.
11
+ - **Meta-Layer Extension**: A self-reflective layer for monitoring, optimization, and auto-generation, enabling AI-driven self-development. Essentially used for extending the core features by using the core features.
12
12
  - **Introspectability**: Exportable graphs, traceable executions, and metadata separation for transparency and debugging.
13
- - **Modularity**: Lightweight core with extensions (e.g., distribution, UI integration) as separate packages.
13
+ - **Modularity**: Lightweight core with extensions (e.g., distribution, UI integration) as separate packages using the meta layer.
14
14
 
15
- The core is suitable for local dynamic workflows using tasks and signals. But thanks to the meta layer, it also serves as the foundation for the distributed, agentic AI applications, and more, abstracting complexities like networking and security in extensions.
15
+ The core is suitable for local dynamic workflows using tasks and signals. But thanks to the meta layer, it also serves as the foundation for distributed applications, and more, abstracting complexities like networking and security in extensions.
16
16
 
17
17
  ## Installation
18
18
 
@@ -25,88 +25,125 @@ npm install @cadenza.io/core
25
25
  ## Usage
26
26
 
27
27
  ### Creating Tasks
28
- Tasks are the atomic units of work in Cadenza. They can be chained to form graphs.
28
+ Tasks are the atomic units of work in Cadenza. They can be chained to form complex graphs.
29
29
 
30
30
  ```typescript
31
31
  import Cadenza from '@cadenza.io/core';
32
32
 
33
- const task1 = Cadenza.createTask('task1', (context) => {
34
- console.log(context.foo);
35
- return { bar: 'baz' };
36
- }, 'First task');
33
+ // Create functions for tasks
34
+ function validateContext(context) {
35
+ if (!context.foo) {
36
+ throw new Error('Missing foo');
37
+ }
38
+ return true;
39
+ }
40
+
41
+ function processContext(context) {
42
+ return { bar: context.foo + '-bar' };
43
+ }
37
44
 
38
- const task2 = Cadenza.createTask('task2', (context) => {
39
- return {...context, qux: 'quux'};
40
- }, 'Second task');
45
+ function logContext(context) {
46
+ console.log(context);
47
+ }
48
+
49
+ // Wrap functions into tasks
50
+ const validateTask = Cadenza.createTask(
51
+ 'Validate context',
52
+ validateContext
53
+ );
41
54
 
42
- const task3 = Cadenza.createTask('task3', (context) => {
43
- return {...context, cadenza: 'is awesome'};
44
- }, 'Third task');
55
+ const processTask = Cadenza.createTask(
56
+ 'Process context',
57
+ processContext,
58
+ );
45
59
 
46
- task1.then(
47
- task2.then(
48
- task3
49
- ),
60
+ const logTask = Cadenza.createTask(
61
+ 'Log context',
62
+ logContext,
50
63
  );
51
64
 
65
+ // Chain tasks together
66
+ validateTask.then(processTask).then(logTask);
67
+
68
+ // Equivalent to:
69
+ const validated = validateContext(context);
70
+ if (validated) {
71
+ const validatedContext = context;
72
+ const processedContext = processContext(validatedContext);
73
+ logContext(processedContext);
74
+ }
52
75
  ```
53
76
 
54
77
  ### Creating Routines
55
78
  Routines are named entry points to graphs.
56
79
 
57
80
  ```typescript
58
- const routine = Cadenza.createRoutine('myRoutine', [task1], 'Test routine');
81
+ const processContextRoutine = Cadenza.createRoutine(
82
+ 'Process context',
83
+ [validateTask],
84
+ 'Processes a context by first validating it, processing the string and logging it.',
85
+ );
59
86
  ```
60
87
 
61
88
  ### Running Graphs
62
89
  Use a Runner to execute routines or tasks.
63
90
 
64
91
  ```typescript
65
- const runner = Cadenza.runner;
66
- await runner.run(routine, {foo: 'bar'});
92
+ Cadenza.run(processContextRoutine);
67
93
  ```
68
94
 
69
95
  ### Signals
70
- Signals provide event-driven coordination.
96
+ Signals provide event-driven coordination. The signal syntax is `domain.event`.
71
97
 
72
98
  ```typescript
73
- task1.emits('my.signal');
74
- task2.doOn('my.other.signal');
75
-
76
- Cadenza.broker.emit('my.other.signal', {foo: 'bar'}); // This will trigger task2
99
+ processContextRoutine.doOn('main.recived_context'); // Subscribe to a signal
100
+ processTask.doOn('main.context_updated'); // Works on tasks and routines
101
+ logTask.emits('process.done'); // Emits after successfull task execution
102
+
103
+ Cadenza.emit('main.recived_context', {foo: 'foo'}); // Emit from anywhere with a context
104
+ Cadenza.emit('main.context_updated', {foo: 'foo-bar'}); // This will trigger the processTask and subsequently logTask. Essentially, skipping the validationTask.
105
+
106
+ // Emit a signal from within a task
107
+ Candenza.createTask('Update context', (ctx, emit) => {
108
+ if (ctx.bar === 'foo-bar') {
109
+ ctx.foo = 'foo-baz';
110
+ emit('main.context_updated', ctx);
111
+ }
112
+ });
77
113
  ```
78
114
 
79
115
  ### Using the Meta Layer
80
116
 
81
- The meta layer serves as a tool for extending the core features. It follows the same rules and primitives as the user layer but runs on a separate meta runner. It consists of MetaTasks, MetaRoutines and meta signals. To trigger a meta flow you need to emit a meta signal (meta.[domain].[action]).
117
+ The meta layer serves as a tool for extending the core features. It follows the same rules and primitives as the user layer but runs on a separate meta runner. It consists of MetaTasks, MetaRoutines and meta signals. To trigger a meta flow you need to emit a meta signal (meta.domain.event).
82
118
 
83
119
  ```typescript
84
120
  Cadenza.createTask('My task', (ctx) => {
85
121
  console.log(ctx.foo);
86
122
  return ctx;
87
- }).emits('meta.some.signal'); // Emits a on task execution
123
+ }).emits('meta.some.event');
88
124
 
89
125
  Cadenza.createMetaTask('My meta task', (ctx) => {
90
126
  console.log(ctx.__task.name);
91
127
  return true;
92
- }).doOn('meta.some.signal');
128
+ })
129
+ .doOn('meta.some.event')
130
+ .emits('meta.some.other_event');
93
131
 
94
- Cadenza.broker.emit('meta.some.signal', {foo: 'bar'}); // Trigger from anywhere
132
+ Cadenza.emit('meta.some.event', {foo: 'bar'}); // Emit from anywhere
95
133
  ```
96
134
 
97
- For full examples, see the [docs folder](docs/examples.md) or the test suite.
135
+ For full examples, see the cadenza-service package (https://github.com/cadenzaio/cadenza-service) or the test suite.
98
136
 
99
137
  ## Features
100
- - **Graph-Based Orchestration**: Define tasks and routines with chaining for dependencies, failovers, and layering.
101
- - **Event-Driven Choreography**: Signals for loose coupling, with meta-signals for self-management.
138
+ - **Graph-Based Orchestration**: Define tasks and routines with chaining for dependencies and layering.
139
+ - **Event-Driven Choreography**: Signals for loose coupling with meta-signals for self-management.
102
140
  - **Context Management**: Immutable contexts with metadata separation and schema validation.
103
- - **Execution Engine**: Sync/async strategies, throttling, debouncing, and unique merging.
104
- - **Bootstrapping**: Lazy initialization with seed tasks for registry and signal handling.
141
+ - **Execution Engine**: Sync/async strategies, throttling, debouncing, fan-in/fan-out merging, dynamic task creation/chaining/deletion.
105
142
 
106
143
  ## Architecture Overview
107
144
  Cadenza's core is divided into:
108
145
  - **Definition Layer**: Task, Routine for static graphs.
109
- - **Execution Layer**: Node, Layer, Builder, Run for runtime.
146
+ - **Execution Layer**: Node, Layer, Builder, Runner for runtime.
110
147
  - **Signal Layer**: SignalBroker, SignalParticipant for coordination.
111
148
  - **Context Layer**: GraphContext for data flow.
112
149
  - **Registry Layer**: GraphRegistry for introspection.
package/dist/index.d.mts CHANGED
@@ -839,8 +839,8 @@ declare class Cadenza {
839
839
  * @throws Error if invalid.
840
840
  */
841
841
  static validateName(name: string): void;
842
- static runTask(task: Task, context: AnyObject): void;
843
- static runRoutine(routine: GraphRoutine, context: AnyObject): void;
842
+ static run(task: Task | GraphRoutine, context: AnyObject): void;
843
+ static emit(event: string, data?: AnyObject): void;
844
844
  /**
845
845
  * Creates a standard Task and registers it in the GraphRegistry.
846
846
  * @param name Unique identifier for the task.
package/dist/index.d.ts CHANGED
@@ -839,8 +839,8 @@ declare class Cadenza {
839
839
  * @throws Error if invalid.
840
840
  */
841
841
  static validateName(name: string): void;
842
- static runTask(task: Task, context: AnyObject): void;
843
- static runRoutine(routine: GraphRoutine, context: AnyObject): void;
842
+ static run(task: Task | GraphRoutine, context: AnyObject): void;
843
+ static emit(event: string, data?: AnyObject): void;
844
844
  /**
845
845
  * Creates a standard Task and registers it in the GraphRegistry.
846
846
  * @param name Unique identifier for the task.
package/dist/index.js CHANGED
@@ -853,7 +853,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
853
853
  }
854
854
  });
855
855
  });
856
- if (context.__previousTaskExecutionId) {
856
+ if (!this.silent && context.__previousTaskExecutionId) {
857
857
  this.emitMetricsWithMetadata(
858
858
  "meta.node.detected_previous_task_execution",
859
859
  {
@@ -3274,11 +3274,11 @@ var Cadenza = class {
3274
3274
  throw new Error("Task or Routine name must be a non-empty string.");
3275
3275
  }
3276
3276
  }
3277
- static runTask(task, context) {
3278
- this.runner.run(task, context);
3277
+ static run(task, context) {
3278
+ this.runner?.run(task, context);
3279
3279
  }
3280
- static runRoutine(routine, context) {
3281
- this.runner.run(routine, context);
3280
+ static emit(event, data = {}) {
3281
+ this.broker?.emit(event, data);
3282
3282
  }
3283
3283
  /**
3284
3284
  * Creates a standard Task and registers it in the GraphRegistry.