@ai.ntellect/core 0.6.11 → 0.6.13

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 (44) hide show
  1. package/app/README.md +36 -0
  2. package/app/app/favicon.ico +0 -0
  3. package/app/app/globals.css +21 -0
  4. package/app/app/gun.ts +0 -0
  5. package/app/app/layout.tsx +18 -0
  6. package/app/app/page.tsx +321 -0
  7. package/app/eslint.config.mjs +16 -0
  8. package/app/next.config.ts +7 -0
  9. package/app/package-lock.json +5912 -0
  10. package/app/package.json +31 -0
  11. package/app/pnpm-lock.yaml +4031 -0
  12. package/app/postcss.config.mjs +8 -0
  13. package/app/public/file.svg +1 -0
  14. package/app/public/globe.svg +1 -0
  15. package/app/public/next.svg +1 -0
  16. package/app/public/vercel.svg +1 -0
  17. package/app/public/window.svg +1 -0
  18. package/app/tailwind.config.ts +18 -0
  19. package/app/tsconfig.json +27 -0
  20. package/dist/graph/controller.js +30 -41
  21. package/dist/graph/graph.js +167 -0
  22. package/dist/index.js +3 -2
  23. package/dist/memory/adapters/meilisearch/index.js +39 -63
  24. package/dist/utils/experimental-graph-rag.js +152 -0
  25. package/dist/utils/stringifiy-zod-schema.js +7 -6
  26. package/graph/controller.ts +57 -52
  27. package/graph/graph.ts +198 -0
  28. package/index.ts +3 -2
  29. package/memory/adapters/meilisearch/index.ts +41 -76
  30. package/package.json +2 -2
  31. package/tsconfig.json +1 -1
  32. package/types/index.ts +35 -38
  33. package/utils/experimental-graph-rag.ts +170 -0
  34. package/utils/stringifiy-zod-schema.ts +6 -6
  35. package/create-llm-to-select-multiple-graph copy.ts +0 -237
  36. package/create-llm-to-select-multiple-graph.ts +0 -148
  37. package/dist/create-llm-to-select-multiple-graph copy.js +0 -171
  38. package/dist/create-llm-to-select-multiple-graph.js +0 -142
  39. package/dist/graph/engine.js +0 -646
  40. package/dist/index copy.js +0 -76
  41. package/dist/utils/setup-graphs.js +0 -28
  42. package/graph/engine.ts +0 -805
  43. package/index copy.ts +0 -81
  44. package/utils/setup-graphs.ts +0 -45
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.experimentalGraphRag = void 0;
13
+ const meilisearch_1 = require("../memory/adapters/meilisearch");
14
+ const embedding_1 = require("../services/embedding");
15
+ const openai_1 = require("@ai-sdk/openai");
16
+ const ai_1 = require("ai");
17
+ const zod_1 = require("zod");
18
+ const experimentalGraphRag = (context) => __awaiter(void 0, void 0, void 0, function* () {
19
+ if (!process.env.MEILISEARCH_API_KEY)
20
+ throw new Error("MEILISEARCH_API_KEY is not set");
21
+ if (!process.env.MEILISEARCH_HOST)
22
+ throw new Error("MEILISEARCH_HOST is not set");
23
+ const memoryManager = new meilisearch_1.MeilisearchAdapter({
24
+ apiKey: process.env.MEILISEARCH_API_KEY,
25
+ host: process.env.MEILISEARCH_HOST,
26
+ });
27
+ yield memoryManager.init("nodes");
28
+ yield memoryManager.init("edges");
29
+ const { existingNodes } = yield retrieveExistingRelations(memoryManager, "nodes");
30
+ const prompt = `
31
+ User asked: ${context.prompt}
32
+ Results: ${JSON.stringify(context.results, null, 2)}
33
+ Existing nodes: ${JSON.stringify(existingNodes, null, 2)}
34
+ `;
35
+ console.log("🔍 Prompt:", prompt);
36
+ const llmMemory = yield (0, ai_1.generateObject)({
37
+ model: (0, openai_1.openai)("gpt-4o"),
38
+ prompt,
39
+ schema: zod_1.z.object({
40
+ nodes: zod_1.z.array(zod_1.z.object({
41
+ name: zod_1.z.string(), // Nom de l'entité (ex: Adresse, ETH, Transaction ID)
42
+ metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.any()), // Métadonnées associées
43
+ })),
44
+ edges: zod_1.z.array(zod_1.z.object({
45
+ source: zod_1.z.string(), // ID de l'entité source
46
+ target: zod_1.z.string(), // ID de l'entité cible
47
+ relation: zod_1.z.string(), // Type de relation (ex: "sent", "received", "on_chain")
48
+ })),
49
+ }),
50
+ system: `
51
+ You are an **AI memory manager** for a crypto wallet assistant.
52
+
53
+ ## Rules:
54
+ - Nodes are entities like user, networks, tokens...etc
55
+ - Relations are edges like sent, uses, supported_on, loves, has_website...etc
56
+ - Ensure NO DUPLICATE RELATIONS.
57
+ - Standardize all relations using Cypher language.
58
+
59
+ Return the structured memory in JSON format, ensuring it follows the schema.
60
+
61
+ Generate structured graph data accordingly.
62
+
63
+ Format the output as a JSON object :
64
+ {
65
+ nodes: [
66
+ {
67
+ name: string,
68
+ metadata: Record<string, any>,
69
+ },
70
+ ],
71
+ edges: [
72
+ {
73
+ source: string,
74
+ target: string,
75
+ relation: string,
76
+ },
77
+ ],
78
+ }
79
+ `,
80
+ });
81
+ console.log("🔍 LLM memory (graph-based):");
82
+ console.log("Nodes:");
83
+ console.dir(llmMemory.object.nodes, { depth: null, colors: true });
84
+ console.log("Edges:");
85
+ console.dir(llmMemory.object.edges, { depth: null, colors: true });
86
+ const embeddingManager = new embedding_1.AIEmbeddingService(openai_1.openai.embedding("text-embedding-3-small"));
87
+ const embedding = yield embeddingManager.embedText(context.prompt);
88
+ let nodesNameToId = {};
89
+ for (const node of llmMemory.object.nodes) {
90
+ // Search for existing memory with same data and query
91
+ const searchResults = yield memoryManager.search(node.name, "nodes", {
92
+ limit: 1,
93
+ });
94
+ const existingMemory = searchResults.find((result) => result.document.data.name === node.name &&
95
+ result.document.roomId === "nodes");
96
+ // If found, return existing memory
97
+ if (existingMemory) {
98
+ nodesNameToId[node.name] = existingMemory.document.id;
99
+ }
100
+ else {
101
+ const nodesMemory = yield memoryManager.createMemory({
102
+ data: node,
103
+ embedding,
104
+ roomId: "nodes",
105
+ });
106
+ nodesNameToId[node.name] = (nodesMemory === null || nodesMemory === void 0 ? void 0 : nodesMemory.id) || "";
107
+ }
108
+ }
109
+ for (const edge of llmMemory.object.edges) {
110
+ // Verify if source and target already exist in memory
111
+ const searchResults = yield memoryManager.search(nodesNameToId[edge.source], "edges", {
112
+ limit: 100,
113
+ });
114
+ const existingEdge = searchResults.find((result) => result.document.data.source === nodesNameToId[edge.source] &&
115
+ result.document.data.target === nodesNameToId[edge.target] &&
116
+ result.document.data.relation === edge.relation);
117
+ if (existingEdge) {
118
+ }
119
+ else {
120
+ yield memoryManager.createMemory({
121
+ data: {
122
+ source: nodesNameToId[edge.source],
123
+ target: nodesNameToId[edge.target],
124
+ relation: edge.relation,
125
+ },
126
+ embedding,
127
+ roomId: "edges",
128
+ });
129
+ }
130
+ }
131
+ });
132
+ exports.experimentalGraphRag = experimentalGraphRag;
133
+ function retrieveExistingRelations(memoryManager, roomId) {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ const existingNodesMemories = yield memoryManager.getAllMemories("nodes");
136
+ const existingEdgesMemories = yield memoryManager.getAllMemories("edges");
137
+ let existingNodes = [];
138
+ let existingEdges = [];
139
+ if (existingNodesMemories.length > 0) {
140
+ existingNodes = existingNodesMemories.flatMap((memory) => {
141
+ return {
142
+ id: memory.id,
143
+ data: memory.data,
144
+ };
145
+ });
146
+ }
147
+ if (existingEdgesMemories.length > 0) {
148
+ existingEdges = existingEdgesMemories.flatMap((memory) => memory.data || []);
149
+ }
150
+ return { existingNodes, existingEdges };
151
+ });
152
+ }
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringifyZodSchema = void 0;
3
+ exports.getSchemaString = exports.stringifyZodSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const stringifyZodSchema = (nodes) => {
6
6
  return nodes
7
7
  .map((node) => {
8
- const schemaStr = node.schema
9
- ? getSchemaString(node.schema)
8
+ const schemaStr = node.parameters
9
+ ? (0, exports.getSchemaString)(node.parameters)
10
10
  : "No parameters";
11
- return `Workflow: ${node.name}\nDescription: ${node.description}\nParameters: ${schemaStr}`;
11
+ return `Workflow: ${node.name}\nParameters: ${schemaStr}`;
12
12
  })
13
13
  .join("\n\n");
14
14
  };
@@ -18,7 +18,7 @@ const getSchemaString = (schema) => {
18
18
  const entries = Object.entries(schema.shape);
19
19
  const fields = entries.map(([key, value]) => {
20
20
  const description = value._def.description;
21
- const schemaStr = getSchemaString(value);
21
+ const schemaStr = (0, exports.getSchemaString)(value);
22
22
  return description
23
23
  ? `${key}: ${schemaStr} // ${description}`
24
24
  : `${key}: ${schemaStr}`;
@@ -26,7 +26,7 @@ const getSchemaString = (schema) => {
26
26
  return `z.object({${fields.join(", ")}})`;
27
27
  }
28
28
  if (schema instanceof zod_1.z.ZodArray) {
29
- return `z.array(${getSchemaString(schema.element)})`;
29
+ return `z.array(${(0, exports.getSchemaString)(schema.element)})`;
30
30
  }
31
31
  if (schema instanceof zod_1.z.ZodString) {
32
32
  return "z.string()";
@@ -39,3 +39,4 @@ const getSchemaString = (schema) => {
39
39
  }
40
40
  return `z.unknown()`;
41
41
  };
42
+ exports.getSchemaString = getSchemaString;
@@ -1,62 +1,67 @@
1
- import { GraphDefinition } from "@/types";
2
- import { GraphEngine } from "./engine";
1
+ import { GraphContext } from "@/types";
2
+ import { ZodSchema } from "zod";
3
+ import { Graph } from "./graph";
3
4
 
4
- /**
5
- * Controller responsible for executing workflows based on graph definitions.
6
- * @template T The type representing the graph's state.
7
- */
8
- export class GraphController<T> {
9
- /**
10
- * Executes a sequence of actions using the corresponding graph definitions.
11
- * @param {any[]} actions - The list of actions to execute.
12
- * @param {GraphDefinition<T>[]} graphs - The available graph definitions.
13
- * @returns {Promise<any>} The final state of the executed workflow.
14
- * @throws {Error} If no actions are provided or if the graph is not found.
15
- */
16
- async run(actions: any[], graphs: GraphDefinition<T>[]): Promise<any> {
17
- if (actions.length === 0) {
18
- throw new Error("No actions provided");
5
+ export class GraphController {
6
+ static async executeSequential<T extends ZodSchema>(
7
+ graphs: Graph<T>[],
8
+ startNodes: string[],
9
+ inputContexts?: Partial<GraphContext<T>>[]
10
+ ): Promise<Map<string, GraphContext<T>>> {
11
+ const results = new Map<string, GraphContext<T>>();
12
+ for (let i = 0; i < graphs.length; i++) {
13
+ const result = await graphs[i].execute(startNodes[i], inputContexts?.[i]);
14
+ results.set(`${graphs[i].name}-${i}`, result);
19
15
  }
16
+ return results;
17
+ }
20
18
 
21
- // Create a mapping of graph names to their definitions for quick lookup.
22
- const graphMap = new Map(graphs.map((g) => [g.name, g]));
23
-
24
- for (const action of actions) {
25
- // Retrieve the graph definition based on the action name.
26
- const graphDefinition = graphMap.get(action.name);
27
- if (!graphDefinition) {
28
- throw new Error(`Graph not found: ${action.name}`);
29
- }
30
-
31
- // Initialize the graph engine with the selected graph definition.
32
- const graph = new GraphEngine(graphDefinition, {
33
- schema: graphDefinition.schema,
34
- autoDetectCycles: true,
35
- });
36
-
37
- console.log("graph", graph);
19
+ static async executeParallel<T extends ZodSchema>(
20
+ graphs: Graph<T>[],
21
+ startNodes: string[],
22
+ inputContexts?: Partial<GraphContext<T>>[],
23
+ inputParams?: any[],
24
+ concurrencyLimit?: number
25
+ ): Promise<Map<string, GraphContext<T>>> {
26
+ const results = new Map<string, GraphContext<T>>();
38
27
 
39
- // Construct the initial state from action parameters.
40
- const initialState = action.parameters.reduce(
41
- (acc: Record<string, any>, param: { name: string; value: any }) => {
42
- acc[param.name] = param.value;
43
- return acc;
44
- },
45
- {}
46
- );
47
-
48
- console.log("initialState", initialState);
28
+ if (inputContexts) {
29
+ inputContexts = inputContexts.map((ctx) => ctx || {});
30
+ }
49
31
 
50
- // Execute the graph starting from the defined entry node.
51
- await graph.execute(initialState, graphDefinition.entryNode);
32
+ if (inputParams) {
33
+ inputParams = inputParams.map((params) => params || {});
34
+ }
52
35
 
53
- // Retrieve the final state after execution.
54
- const result = graph.getState();
55
- if (!result) {
56
- throw new Error("Workflow execution failed to return a state");
36
+ if (concurrencyLimit) {
37
+ for (let i = 0; i < graphs.length; i += concurrencyLimit) {
38
+ const batchResults = await Promise.all(
39
+ graphs.slice(i, i + concurrencyLimit).map((graph, index) =>
40
+ graph.execute(
41
+ startNodes[i + index],
42
+ inputContexts?.[i + index] || {},
43
+ inputParams?.[i + index] || {} // ✅ Passe bien les paramètres
44
+ )
45
+ )
46
+ );
47
+ batchResults.forEach((result, index) => {
48
+ results.set(`${graphs[i + index].name}`, result);
49
+ });
57
50
  }
58
-
59
- return result;
51
+ } else {
52
+ const allResults = await Promise.all(
53
+ graphs.map((graph, index) =>
54
+ graph.execute(
55
+ startNodes[index],
56
+ inputContexts?.[index] || {},
57
+ inputParams?.[index] || {}
58
+ )
59
+ )
60
+ );
61
+ allResults.forEach((result, index) => {
62
+ results.set(`${graphs[index].name}`, result);
63
+ });
60
64
  }
65
+ return results;
61
66
  }
62
67
  }
package/graph/graph.ts ADDED
@@ -0,0 +1,198 @@
1
+ import { GraphConfig, GraphContext, GraphDefinition, Node } from "@/types";
2
+ import { configDotenv } from "dotenv";
3
+ import EventEmitter from "events";
4
+ import { ZodSchema } from "zod";
5
+ configDotenv();
6
+
7
+ // Classe Graph avec un contexte typé
8
+ export class Graph<T extends ZodSchema> {
9
+ private nodes: Map<string, Node<T>>;
10
+ private context: GraphContext<T>;
11
+ public validator?: T;
12
+ private eventEmitter: EventEmitter;
13
+ private globalErrorHandler?: (error: Error, context: GraphContext<T>) => void;
14
+
15
+ constructor(public name: string, config: GraphConfig<T>) {
16
+ this.nodes = new Map(config.nodes.map((node) => [node.name, node]));
17
+ this.context = config.initialContext || ({} as GraphContext<T>);
18
+ this.validator = config.validator;
19
+ this.globalErrorHandler = config.globalErrorHandler;
20
+ this.eventEmitter = new EventEmitter();
21
+ this.setupEventListeners();
22
+ }
23
+
24
+ private createNewContext(): GraphContext<T> {
25
+ return structuredClone(this.context);
26
+ }
27
+
28
+ private setupEventListeners(): void {
29
+ for (const node of this.nodes.values()) {
30
+ node.events?.forEach((event) => {
31
+ this.eventEmitter.on(event, async (data?: Partial<GraphContext<T>>) => {
32
+ const context = this.createNewContext();
33
+ if (data) Object.assign(context, data);
34
+ await this.executeNode(node.name, context);
35
+ });
36
+ });
37
+ }
38
+ }
39
+ private async executeNode(
40
+ nodeName: string,
41
+ context: GraphContext<T>,
42
+ params?: any
43
+ ): Promise<void> {
44
+ const node = this.nodes.get(nodeName);
45
+ if (!node) throw new Error(`❌ Node ${nodeName} not found`);
46
+
47
+ if (node.condition && !node.condition(context)) return;
48
+
49
+ let attempts = 0;
50
+ const maxAttempts = node.retry?.maxAttempts || 1;
51
+ const delay = node.retry?.delay || 0;
52
+
53
+ while (attempts < maxAttempts) {
54
+ try {
55
+ let validatedParams;
56
+
57
+ // ✅ Si le nœud a un `parameters`, on valide `params` avant exécution
58
+ if (node.parameters) {
59
+ if (!params) {
60
+ throw new Error(
61
+ `❌ Paramètres requis pour le nœud "${nodeName}" mais reçus: ${params}`
62
+ );
63
+ }
64
+ validatedParams = node.parameters.parse(params);
65
+ }
66
+
67
+ // ✅ Exécuter avec ou sans `params`
68
+ if (node.execute) {
69
+ await node.execute(context);
70
+ } else if (node.executeWithParams) {
71
+ if (!validatedParams) {
72
+ throw new Error(
73
+ `❌ Paramètres invalides pour le nœud "${nodeName}"`
74
+ );
75
+ }
76
+ await node.executeWithParams(context, validatedParams);
77
+ }
78
+
79
+ this.validateContext(context);
80
+
81
+ this.eventEmitter.emit("nodeCompleted", { nodeName, context });
82
+
83
+ if (node.next) {
84
+ await Promise.all(
85
+ node.next.map((nextNode) => this.executeNode(nextNode, context))
86
+ );
87
+ }
88
+ return;
89
+ } catch (error) {
90
+ attempts++;
91
+
92
+ if (attempts >= maxAttempts) {
93
+ this.eventEmitter.emit("nodeError", { nodeName, error });
94
+ node.onError?.(error as Error);
95
+ this.globalErrorHandler?.(error as Error, context);
96
+ throw error;
97
+ }
98
+
99
+ console.warn(
100
+ `[Graph ${this.name}] Retry attempt ${attempts} for node ${nodeName}`,
101
+ { error }
102
+ );
103
+
104
+ await new Promise((resolve) => setTimeout(resolve, delay));
105
+ }
106
+ }
107
+ }
108
+
109
+ private validateContext(context: GraphContext<T>): void {
110
+ if (this.validator) {
111
+ this.validator.parse(context);
112
+ }
113
+ }
114
+
115
+ async execute(
116
+ startNode: string,
117
+ inputContext?: Partial<GraphContext<T>>,
118
+ inputParams?: any
119
+ ): Promise<GraphContext<T>> {
120
+ const context = this.createNewContext();
121
+ if (inputContext) Object.assign(context, inputContext);
122
+
123
+ this.eventEmitter.emit("graphStarted", { name: this.name });
124
+ try {
125
+ await this.executeNode(startNode, context, inputParams);
126
+ this.eventEmitter.emit("graphCompleted", { name: this.name, context });
127
+ return context;
128
+ } catch (error) {
129
+ this.eventEmitter.emit("graphError", { name: this.name, error });
130
+ this.globalErrorHandler?.(error as Error, context); // Gestionnaire d'erreurs global
131
+ throw error;
132
+ }
133
+ }
134
+
135
+ emit(
136
+ eventName: string,
137
+ data?: Partial<GraphContext<T>>
138
+ ): Promise<GraphContext<T>> {
139
+ return new Promise((resolve, reject) => {
140
+ if (data) Object.assign(this.context, data); // ✅ Met à jour le contexte global
141
+
142
+ this.eventEmitter.emit(eventName, this.context); // Utilise le contexte global
143
+
144
+ const eventNodes = Array.from(this.nodes.values()).filter((node) =>
145
+ node.events?.includes(eventName)
146
+ );
147
+ if (eventNodes.length === 0) return resolve(this.context);
148
+
149
+ Promise.all(
150
+ eventNodes.map(
151
+ (node) =>
152
+ new Promise<void>((resolve) => {
153
+ this.eventEmitter.once("nodeCompleted", ({ nodeName }) => {
154
+ if (nodeName === node.name) resolve();
155
+ });
156
+ })
157
+ )
158
+ )
159
+ .then(() => resolve(this.context))
160
+ .catch(reject);
161
+ });
162
+ }
163
+
164
+ on(eventName: string, handler: (...args: any[]) => void): void {
165
+ this.eventEmitter.on(eventName, handler);
166
+ }
167
+
168
+ loadDefinition(definition: GraphDefinition<T>): void {
169
+ this.nodes.clear();
170
+ Object.values(definition.nodes).forEach((node) =>
171
+ this.nodes.set(node.name, node)
172
+ );
173
+ this.setupEventListeners();
174
+ }
175
+
176
+ getContext(): GraphContext<T> {
177
+ return structuredClone(this.context);
178
+ }
179
+
180
+ // Journalisation (logging)
181
+ log(message: string, data?: any): void {
182
+ console.log(`[Graph ${this.name}] ${message}`, data);
183
+ }
184
+
185
+ // Modification dynamique du graph
186
+ addNode(node: Node<T>): void {
187
+ this.nodes.set(node.name, node);
188
+ this.setupEventListeners();
189
+ }
190
+
191
+ removeNode(nodeName: string): void {
192
+ this.nodes.delete(nodeName);
193
+ }
194
+
195
+ getNodes(): Node<T>[] {
196
+ return Array.from(this.nodes.values());
197
+ }
198
+ }
package/index.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  export * from "./graph/controller";
2
- export * from "./graph/engine";
2
+ export * from "./graph/graph";
3
3
  export * from "./memory";
4
4
  export * from "./memory/adapters/meilisearch";
5
5
  export * from "./memory/adapters/redis";
6
6
 
7
7
  export * from "./interfaces";
8
+ export * from "./services/agenda";
9
+ export * from "./services/embedding";
8
10
  export * from "./types";
9
- export * from "./utils/setup-graphs";
10
11
  export * from "./utils/stringifiy-zod-schema";