@ai.ntellect/core 0.6.13 → 0.6.14

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.
Files changed (3) hide show
  1. package/README.md +175 -332
  2. package/graph/graph.ts +0 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,404 +1,247 @@
1
1
  # @ai.ntellect/core
2
2
 
3
- ---
3
+ A powerful framework for building AI-powered applications with graph-based workflows, memory management, and embedding services.
4
4
 
5
- ## Introduction
5
+ ## Features
6
6
 
7
- **@ai.ntellect/core** is a highly extensible, graph-based workflow framework designed to tackle complex automation scenarios, pipelines, AI-driven agent flows, and even blockchain process orchestration. By modeling your processes as **Graphs** composed of **Nodes**, you can intuitively define both sequential and parallel task execution. The framework provides robust features including:
8
-
9
- - **Dynamic state management** with optional schema validation
10
- - **Parallel and conditional branching** execution
11
- - **Controller-based orchestration** of multiple workflows
12
- - **Subgraph** delegation for modular design
13
- - **Memory management** for agents and chatbots (e.g., storing user context or embeddings)
14
- - **Integration** with real-time notifiers and persistence layers
15
-
16
- Whether you’re building a data pipeline, an AI-driven bot, or an automated blockchain process, @ai.ntellect/core offers a concise yet powerful suite of tooling to handle the complexity of stateful, event-driven orchestration.
17
-
18
- ---
7
+ - 🔄 **Graph-based workflow engine**: Build complex, type-safe workflows with retry mechanisms and error handling
8
+ - 🧠 **Memory management**: Store and retrieve AI-related data with multiple storage adapters (Meilisearch, Redis)
9
+ - 🔍 **Embedding services**: Generate and compare text embeddings for semantic search and similarity matching
10
+ - **Task scheduling**: Schedule and manage recurring tasks with cron expressions
19
11
 
20
12
  ## Installation
21
13
 
22
- ### Prerequisites
23
-
24
- - **Node.js** (14.x or higher recommended)
25
- - A package manager such as **npm** or **yarn**
26
-
27
- ### Installing the package
28
-
29
14
  ```bash
30
15
  npm install @ai.ntellect/core
31
16
  ```
32
17
 
33
- Or using Yarn:
34
-
35
- ```bash
36
- yarn add @ai.ntellect/core
37
- ```
38
-
39
- Or using pnpm:
40
-
41
- ```bash
42
- pnpm add @ai.ntellect/core
43
- ```
44
-
45
- ### Initial configuration
18
+ ## Core components
46
19
 
47
- - **Import the necessary classes**:
20
+ The Graph system is the heart of the framework, enabling dynamic and highly flexible workflows.
48
21
 
49
- ```ts
50
- import { GraphEngine, GraphController } from "@ai.ntellect/core";
51
- ```
22
+ ### Basic graph structure
52
23
 
53
- - **(Optional) Define your state schema** using a validation library like [Zod](https://zod.dev) to ensure your data remains consistent throughout workflow execution.
54
- - **Configure** advanced features (e.g., persistence, notifications, memory services) before running your workflows.
24
+ ```typescript
25
+ import { Graph, GraphContext } from "@ai.ntellect/core";
26
+ import { z } from "zod";
55
27
 
56
- ---
57
-
58
- ## Core concepts
59
-
60
- @ai.ntellect/core revolves around the idea of **Graphs** and **Nodes**. On top of these concepts, the framework provides a powerful **Engine**, a high-level **Controller**, and optional **Memory** management for specialized use cases (like AI agents). This section explores each concept in detail.
61
-
62
- ### Graph
63
-
64
- A **Graph** is a directed structure describing a workflow. It consists of:
65
-
66
- - **Nodes**: the tasks or steps in your workflow
67
- - **Edges (relationships)**: transitions from one node to another
68
-
69
- You define a **Graph** via a `GraphDefinition`, specifying:
70
-
71
- 1. A unique **name** for the graph
72
- 2. An **entryNode** (starting point)
73
- 3. A map of **node objects** (each one describes a single node’s logic and transitions)
74
-
75
- #### Why use graphs?
76
-
77
- - **Clear visualization**: easily see the flow of tasks, including parallel branches.
78
- - **Condition-based transitions**: skip or filter nodes on the fly.
79
- - **Subgraph usage**: encapsulate common flows for reuse.
80
-
81
- #### Example of a simple graph definition
28
+ // Context Schema Definition
29
+ const contextSchema = z.object({
30
+ input: z.string(),
31
+ result: z.number().optional(),
32
+ error: z.string().optional(),
33
+ });
82
34
 
83
- ```ts
84
- const myGraphDefinition = {
85
- name: "my-simple-graph",
86
- entryNode: "start",
87
- nodes: {
88
- start: {
89
- name: "start",
90
- execute: async (_params, state) => {
91
- return { context: { ...state.context, status: "initialized" } };
35
+ // Graph Creation
36
+ const workflow = new Graph("processWorkflow", {
37
+ name: "workflow",
38
+ nodes: [
39
+ {
40
+ name: "inputValidation",
41
+ execute: async (context) => {
42
+ if (context.input.length < 3) {
43
+ context.error = "Input too short";
44
+ }
92
45
  },
93
- relationships: [{ name: "process" }],
46
+ next: ["processing"],
94
47
  },
95
- process: {
96
- name: "process",
97
- execute: async (_params, state) => {
98
- // do something
99
- return { context: { ...state.context, processed: true } };
48
+ {
49
+ name: "processing",
50
+ condition: (context) => !context.error,
51
+ execute: async (context) => {
52
+ context.result = context.input.length;
100
53
  },
101
- relationships: [{ name: "finish" }],
54
+ next: ["finalValidation"],
102
55
  },
103
- finish: {
104
- name: "finish",
105
- execute: async (_params, state) => state,
106
- relationships: [],
56
+ {
57
+ name: "finalValidation",
58
+ execute: async (context) => {
59
+ if (context.result && context.result < 10) {
60
+ context.error = "Result too small";
61
+ }
62
+ },
107
63
  },
64
+ ],
65
+ initialContext: {
66
+ input: "",
67
+ result: undefined,
68
+ error: undefined,
69
+ },
70
+ validator: contextSchema,
71
+ globalErrorHandler: (error, context) => {
72
+ console.error("Global error:", error);
108
73
  },
109
- };
74
+ });
110
75
  ```
111
76
 
112
- ### Node
113
-
114
- A **Node** is a fundamental unit of work within a graph. Each node defines:
115
-
116
- - **name**: a unique identifier within the graph
117
- - **execute**: the asynchronous function that implements the node’s logic
118
- - **condition** (optional): a function returning a boolean determining if this node should run
119
- - **relationships**: an array of transitions to subsequent nodes
120
- - **events** (optional): an array of event names that can trigger the node (bypassing usual transitions)
77
+ ## Advanced graph features
121
78
 
122
- #### Listening to events
79
+ ### 1. Nodes with conditions
123
80
 
124
- Besides sequential or parallel execution, a node can listen to custom events:
81
+ Add sophisticated conditions for node execution:
125
82
 
126
- ```ts
83
+ ```typescript
127
84
  {
128
- name: "eventDrivenNode",
129
- events: ["USER_CREATED"],
130
- execute: async (params, state) => {
131
- console.log("User created:", params);
132
- return state;
133
- },
85
+ name: "conditionalNode",
86
+ // Execute the node only if the condition is met
87
+ condition: (context) => context.result > 10,
88
+ execute: async (context) => {
89
+ // Conditional logic
90
+ }
134
91
  }
135
92
  ```
136
93
 
137
- If the **Engine** later calls `engine.emit("USER_CREATED", {...})`, this node will be triggered. This mechanism is extremely powerful for event-driven architectures (e.g., a chatbot responding to user events, or a blockchain node responding to on-chain events).
138
-
139
- ### GraphEngine
140
-
141
- #### Overview
142
-
143
- The **GraphEngine** (often shortened to “engine”) is responsible for:
144
-
145
- - Loading a `GraphDefinition`
146
- - Executing its nodes according to **relationships** and optional **conditions**
147
- - Handling **state** updates after each node execution
148
- - Managing **event** emissions and listening for event-driven nodes
149
- - Allowing **parallel** or **sequential** node execution
150
- - Managing **subgraphs** if your workflow references external graph definitions
151
-
152
- ```ts
153
- import { GraphEngine } from "ai.ntellect/core";
154
-
155
- const engine = new GraphEngine(myGraphDefinition);
156
- await engine.execute({ context: { user: "Alice" } }, "start");
157
- ```
158
-
159
- ### GraphController
160
-
161
- #### Overview
162
-
163
- The **GraphController** provides a **high-level orchestration** mechanism for multiple graphs. Instead of running a single workflow, you can define **actions**—each tied to a particular workflow—and the controller executes them in sequence (or other patterns) based on your configuration.
164
-
165
- ```ts
166
- import { GraphController } from "ai.ntellect/core";
94
+ ### 2. Error handling
167
95
 
168
- const controller = new GraphController<any>();
169
- const resultState = await controller.run(
170
- [
171
- {
172
- name: "my-simple-graph",
173
- parameters: [
174
- { name: "user", value: "Alice" },
175
- { name: "count", value: 10 },
176
- ],
177
- },
178
- ],
179
- [myGraphDefinition, someOtherGraphDef]
180
- );
181
-
182
- console.log(resultState);
183
- // => final state after running 'my-simple-graph'
184
- ```
185
-
186
- **Use cases**:
187
-
188
- - **Batch execution** of multiple workflows
189
- - **Multi-tenant** orchestration where each tenant’s configuration is an “action”
190
- - **Chained flows**: run workflow A, then run workflow B with the result of A
191
-
192
- ### Memory management
193
-
194
- In advanced workflows, especially with chatbots or AI agents, you might want to maintain a **memory** of previous interactions or references. @ai.ntellect/core accommodates this via an abstract class **BaseMemory** and a dedicated **BaseMemoryService** for storing and retrieving data. This can be used to store embeddings, historical context, or any ephemeral data needed for your workflows.
195
-
196
- ```ts
197
- import { BaseMemory } from "ai.ntellect/core";
198
-
199
- // Example concrete class
200
- class MyMemory extends BaseMemory {
201
- async init(): Promise<void> {
202
- /*...*/
203
- }
204
- async createMemory(input): Promise<BaseMemoryType | undefined> {
205
- /*...*/
206
- }
207
- async getMemoryById(id, roomId): Promise<BaseMemoryType | null> {
208
- /*...*/
96
+ ```typescript
97
+ {
98
+ name: "unreliableOperation",
99
+ retry: {
100
+ // Maximum number of attempts
101
+ maxAttempts: 3,
102
+ // Delay between attempts
103
+ delay: 1000 // 1 second
104
+ },
105
+ execute: async (context) => {
106
+ // Potentially unstable operation
107
+ },
108
+ // Node-specific error handler
109
+ onError: (error) => {
110
+ console.warn("Node error:", error);
209
111
  }
210
- // ... other methods
211
112
  }
212
113
  ```
213
114
 
214
- **Possible storage backends**:
215
-
216
- - In-memory
217
- - Redis / Key-value stores
218
- - SQL / NoSQL databases
219
-
220
- **Key benefits**:
221
-
222
- - Store query embeddings for AI-based search
223
- - Maintain user session context (e.g., conversation flows)
224
- - Rapidly retrieve and update relevant data at runtime
225
-
226
- ---
227
-
228
- ## Advanced usage and features
229
-
230
- ### Subgraphs for modularity
231
-
232
- Nodes can delegate execution to a **subgraph**, enabling large workflows to be broken into reusable components:
233
-
234
- ```ts
235
- const subGraphEngine = new GraphEngine(subGraphDef);
236
- mainGraphEngine.addSubGraph(subGraphEngine, "sub-start", "sub-workflow");
237
- ```
238
-
239
- **Why subgraphs**:
240
-
241
- - **Reusability**: common routines can be maintained independently
242
- - **Maintainability**: isolate large logic in smaller workflows
243
-
244
- ### Parallel execution
115
+ ### 3. Dynamic and parallel execution
245
116
 
246
- The `executeParallel` method allows you to simultaneously run multiple nodes that don’t have direct dependencies on each other. You can limit concurrency to prevent overwhelming external resources:
247
-
248
- ```ts
249
- await engine.executeParallel(
250
- { context: { userId: 42 } },
251
- ["nodeA", "nodeB", "nodeC"],
252
- 2 // concurrency limit
117
+ ```typescript
118
+ // Execute multiple graphs in parallel
119
+ const results = await GraphController.executeParallel(
120
+ [graph1, graph2, graph3],
121
+ ["startNode1", "startNode2", "startNode3"],
122
+ [context1, context2, context3],
123
+ undefined, // parameters
124
+ 3 // concurrency limit
253
125
  );
254
126
  ```
255
127
 
256
- ### Real-time notifications and events
128
+ ### 4. Events
257
129
 
258
- By attaching a **RealTimeNotifier**, each node’s start, completion, or error can be broadcast to external systems (WebSocket, Slack, logging, etc.):
130
+ ```typescript
131
+ workflow.on("nodeCompleted", (data) => {
132
+ console.log(`Node ${data.nodeName} completed`);
133
+ });
259
134
 
260
- ```ts
261
- const notifier = {
262
- notify: (event, data) => {
263
- console.log(`[NOTIFY] ${event}`, data);
264
- },
265
- };
266
- engine.setNotifier(notifier);
135
+ // Emit custom events
136
+ await workflow.emit("customEvent", {
137
+ additionalData: "value",
138
+ });
267
139
  ```
268
140
 
269
- ### Persistence and error recovery
270
-
271
- For long-running or mission-critical workflows, implement a **Persistence** interface:
141
+ ### 5. Dynamic graph modification
272
142
 
273
- ```ts
274
- const myPersistence = {
275
- saveState: async (graphName, state, currentNode) => {
276
- /* store in DB */
143
+ ```typescript
144
+ // Dynamically add nodes
145
+ workflow.addNode({
146
+ name: "newNode",
147
+ execute: async (context) => {
148
+ // New logic
277
149
  },
278
- loadState: async () => {
279
- /* retrieve from DB */ return null;
280
- },
281
- };
282
- engine.setPersistence(myPersistence);
283
- ```
150
+ });
284
151
 
285
- If a workflow fails, you can reload from the last checkpoint and resume execution.
152
+ // Remove nodes
153
+ workflow.removeNode("obsoleteNode");
154
+ ```
286
155
 
287
- ---
156
+ ### 6. Context validation with Zod
288
157
 
289
- ## Example: agent workflow with memory
158
+ Use Zod for runtime context validation:
290
159
 
291
- Below is an example `createMainGraph` definition demonstrating how you can structure an AI or chatbot-like agent using a controller node, agenda scheduling, interpretation, and memory storage. This pattern is useful in:
160
+ ```typescript
161
+ const strictContextSchema = z.object({
162
+ // Define precise rules
163
+ input: z.string().min(3).max(100),
164
+ result: z.number().positive(),
165
+ timestamp: z.date(),
166
+ });
292
167
 
293
- - **Chatbots** handling complex dialogues
294
- - **AI reasoning systems** that need to store partial results
295
- - **Planning agents** that schedule tasks or actions asynchronously
168
+ const workflow = new Graph("strictWorkflow", {
169
+ // The validator will check each context modification
170
+ validator: strictContextSchema,
171
+ });
172
+ ```
296
173
 
297
- ```ts
298
- import { GraphDefinition } from "@/types";
299
- // Assume Agent, MyContext, isNotStopped, shouldRetry, etc. are defined
174
+ ## Complete example: Data processing workflow
300
175
 
301
- export const createMainGraph = (
302
- agent: Agent,
303
- prompt: string,
304
- callbacks?: any
305
- ): GraphDefinition<MyContext> => ({
306
- name: "agent",
307
- entryNode: "orchestrator",
308
- nodes: {
309
- orchestrator: {
310
- name: "orchestrator",
311
- description: "Make a decision following the current context",
312
- execute: async () => {
313
- /* your orchestrator logic */
314
- },
315
- condition: (state) => isNotStopped(state) || shouldRetry(state),
316
- relationships: [
317
- { name: "controller", description: "Execute multiple workflows" },
318
- { name: "agenda", description: "Schedule actions for the future" },
319
- {
320
- name: "interpreter",
321
- description: "Interpret the results of actions",
322
- },
323
- ],
324
- },
325
- controller: {
326
- name: "controller",
327
- description: "Execute multiple workflows if available",
328
- execute: async () => {
329
- /* handle or queue workflow actions */
330
- },
331
- condition: () => {
332
- const currentState = agent.graph.getState();
333
- return hasActions(currentState) && isNotStopped(currentState);
176
+ ```typescript
177
+ const dataProcessingWorkflow = new Graph("dataProcessor", {
178
+ nodes: [
179
+ {
180
+ name: "dataFetch",
181
+ execute: async (context) => {
182
+ context.rawData = await fetchData();
334
183
  },
335
- relationships: [{ name: "orchestrator" }],
184
+ next: ["dataValidation"],
336
185
  },
337
- agenda: {
338
- name: "agenda",
339
- description: "Schedule actions for the future",
340
- execute: async () => {
341
- /* handle scheduling logic */
186
+ {
187
+ name: "dataValidation",
188
+ condition: (context) => context.rawData.length > 0,
189
+ execute: async (context) => {
190
+ context.validatedData = validateData(context.rawData);
342
191
  },
343
- condition: hasActions,
192
+ next: ["dataTransformation"],
344
193
  },
345
- interpreter: {
346
- name: "interpreter",
347
- description: "Interpret the results of the actions",
348
- execute: async () => {
349
- /* interpret results, maybe using memory */
350
- },
351
- condition: () => {
352
- const currentState = agent.graph.getState();
353
- return (
354
- isInterpreterDefined(currentState) &&
355
- isResultsDefined(currentState) &&
356
- isStopped(currentState)
357
- );
194
+ {
195
+ name: "dataTransformation",
196
+ execute: async (context) => {
197
+ context.processedData = transformData(context.validatedData);
358
198
  },
359
- relationships: [{ name: "memory", description: "Save memory" }],
199
+ next: ["dataStorage"],
360
200
  },
361
- memory: {
362
- name: "memory",
363
- description: "Save memory",
364
- execute: async () => {
365
- /* store or retrieve conversation states */
366
- },
367
- condition: () => {
368
- const currentState = agent.graph.getState();
369
- return isResultsDefined(currentState);
201
+ {
202
+ name: "dataStorage",
203
+ execute: async (context) => {
204
+ await storeData(context.processedData);
370
205
  },
371
206
  },
372
- },
207
+ ],
373
208
  });
374
209
  ```
375
210
 
376
- This structure highlights how an **Agent** can leverage the **GraphEngine** for decision-making, scheduling tasks, interpreting outcomes, and ultimately storing relevant data in memory before concluding.
211
+ ## Key points
377
212
 
378
- ---
213
+ - **Total flexibility**: Create complex workflows with great freedom
214
+ - **Type safety**: Runtime context and parameter validation
215
+ - **Dynamic management**: Modify graphs during execution
216
+ - **Resilience**: Integrated retry and error handling mechanisms
379
217
 
380
- ## Real-world use cases
218
+ ## GraphController: Advanced execution strategies
381
219
 
382
- 1. **Automation**: Orchestrate tasks like file processing, data validation, and uploading in a single graph.
383
- 2. **Data pipeline**: Stream logs into a transformation flow with parallel processing and conditional branches.
384
- 3. **AI bots**: Manage conversation state, memory, and advanced decision trees for chat-based agents.
385
- 4. **Blockchain**: Sequence complex contract interactions, handle parallel on-chain calls, and revert safely on errors.
386
- 5. **Task scheduling**: Combine GraphController with multiple workflows to handle enterprise-wide daily or weekly tasks.
220
+ ### Sequential execution
387
221
 
388
- ---
389
-
390
- ## Conclusion
391
-
392
- @ai.ntellect/core offers a **comprehensive**, **modular**, and **event-driven** environment to model, execute, and extend workflows of any complexity. By leveraging **Graphs** and **Nodes** alongside robust tooling such as **GraphEngine**, **GraphController**, and **Memory** services, you can adapt the framework to fit an array of domains, from classic data pipelines to cutting-edge AI agent systems.
222
+ ```typescript
223
+ const sequentialResults = await GraphController.executeSequential(
224
+ [graph1, graph2],
225
+ ["startNode1", "startNode2"],
226
+ [context1, context2]
227
+ );
228
+ ```
393
229
 
394
- ### Key points to remember
230
+ ### Parallel execution with concurrency control
395
231
 
396
- - **Graphs** define the structure of your workflow; **Nodes** encapsulate the logic.
397
- - **GraphEngine** executes a single graph, handling state, conditions, and events.
398
- - **GraphController** orchestrates multiple graphs in a higher-level scope.
399
- - **Memory** management supports advanced agent use cases, storing embeddings or conversation history.
400
- - **Parallel execution**, **subgraphs**, **real-time notifications**, and **persistence** provide powerful abstractions to scale with your needs.
232
+ ```typescript
233
+ const parallelResults = await GraphController.executeParallel(
234
+ multipleGraphs,
235
+ startNodes,
236
+ inputContexts,
237
+ inputParams,
238
+ 3 // Maximum 3 graphs executing simultaneously
239
+ );
240
+ ```
401
241
 
402
- For more in-depth guides, examples, or to contribute, visit our repository or consult the extended documentation. If you need specialized solutions—like a custom memory store or a unique scheduling system—**@ai.ntellect/core**’s open architecture makes it straightforward to extend or integrate with your existing stack.
242
+ ## Performance considerations
403
243
 
404
- Use it for automation, AI bots, blockchain interactions, or any stateful workflow that demands reliability, flexibility, and clarity.
244
+ - Use `executeParallel` for independent workflows
245
+ - Implement appropriate concurrency limits
246
+ - Monitor context size and complexity
247
+ - Leverage Zod for efficient runtime validation
package/graph/graph.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { GraphConfig, GraphContext, GraphDefinition, Node } from "@/types";
2
- import { configDotenv } from "dotenv";
3
2
  import EventEmitter from "events";
4
3
  import { ZodSchema } from "zod";
5
- configDotenv();
6
4
 
7
5
  // Classe Graph avec un contexte typé
8
6
  export class Graph<T extends ZodSchema> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai.ntellect/core",
3
- "version": "0.6.13",
3
+ "version": "0.6.14",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {