@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
@@ -1,14 +1,7 @@
1
- import { BaseMemoryService } from "@/interfaces";
2
- import { BaseMemory } from "@/memory";
3
1
  import { BaseMemoryType, CreateMemoryInput, MeilisearchConfig } from "@/types";
4
2
 
5
- export class MeilisearchAdapter extends BaseMemory {
6
- constructor(
7
- private readonly config: MeilisearchConfig,
8
- baseMemoryService: BaseMemoryService
9
- ) {
10
- super(baseMemoryService);
11
- }
3
+ export class MeilisearchAdapter {
4
+ constructor(private readonly config: MeilisearchConfig) {}
12
5
 
13
6
  private async makeRequest(path: string, options?: RequestInit) {
14
7
  try {
@@ -45,31 +38,23 @@ export class MeilisearchAdapter extends BaseMemory {
45
38
  let indexExists = false;
46
39
 
47
40
  try {
48
- // Check if index exists
49
41
  await this.makeRequest(`/indexes/${roomId}`);
50
42
  indexExists = true;
51
43
  } catch (error) {
52
- // Only continue if the error is "Not found"
53
- if (!(error instanceof Error && error.message.includes("Not found"))) {
54
- throw error;
44
+ if (!indexExists) {
45
+ const createResponse = await this.makeRequest("/indexes", {
46
+ method: "POST",
47
+ body: JSON.stringify({
48
+ uid: roomId,
49
+ primaryKey: "id",
50
+ }),
51
+ });
52
+
53
+ console.log("✅ Index creation response:", createResponse);
55
54
  }
56
55
  }
57
56
 
58
- if (!indexExists) {
59
- // Create new index
60
- await this.makeRequest("/indexes", {
61
- method: "POST",
62
- body: JSON.stringify({
63
- uid: roomId,
64
- primaryKey: "id",
65
- }),
66
- });
67
-
68
- // Wait for index creation
69
- await new Promise((resolve) => setTimeout(resolve, 1000));
70
- }
71
-
72
- // Update settings
57
+ // Appliquer les settings seulement si l'index existe bien
73
58
  await this.makeRequest(`/indexes/${roomId}/settings`, {
74
59
  method: "PATCH",
75
60
  body: JSON.stringify({
@@ -84,7 +69,7 @@ export class MeilisearchAdapter extends BaseMemory {
84
69
  const errorMessage =
85
70
  error instanceof Error ? error.message : "Unknown error";
86
71
  console.error(
87
- `Error initializing storage for index ${roomId}:`,
72
+ `❌ Error initializing storage for index ${roomId}:`,
88
73
  errorMessage
89
74
  );
90
75
  throw new Error(
@@ -102,6 +87,24 @@ export class MeilisearchAdapter extends BaseMemory {
102
87
  body: JSON.stringify(documents),
103
88
  });
104
89
  }
90
+ async deleteStorage(roomId: string): Promise<void> {
91
+ await this.makeRequest(`/indexes/${roomId}`, {
92
+ method: "DELETE",
93
+ });
94
+ }
95
+
96
+ // Required BaseMemory implementations
97
+ async init(roomId: string): Promise<void> {
98
+ try {
99
+ // Initialize the default "memories" index
100
+ await this.initializeStorage(roomId);
101
+ } catch (error) {
102
+ const errorMessage =
103
+ error instanceof Error ? error.message : "Unknown error";
104
+ console.error("Failed to initialize default index:", errorMessage);
105
+ throw new Error(`Failed to initialize default index: ${errorMessage}`);
106
+ }
107
+ }
105
108
 
106
109
  async search(
107
110
  query: string,
@@ -120,7 +123,6 @@ export class MeilisearchAdapter extends BaseMemory {
120
123
  document: {
121
124
  id: hit.id,
122
125
  data: hit.data,
123
- query: hit.query,
124
126
  embedding: hit.embedding,
125
127
  roomId: hit.roomId,
126
128
  createdAt: hit.createdAt,
@@ -129,52 +131,16 @@ export class MeilisearchAdapter extends BaseMemory {
129
131
  }));
130
132
  }
131
133
 
132
- async deleteStorage(roomId: string): Promise<void> {
133
- await this.makeRequest(`/indexes/${roomId}`, {
134
- method: "DELETE",
135
- });
136
- }
137
-
138
- // Required BaseMemory implementations
139
- async init(): Promise<void> {
140
- try {
141
- // Initialize the default "memories" index
142
- await this.initializeStorage("memories");
143
- } catch (error) {
144
- const errorMessage =
145
- error instanceof Error ? error.message : "Unknown error";
146
- console.error("Failed to initialize default index:", errorMessage);
147
- throw new Error(`Failed to initialize default index: ${errorMessage}`);
148
- }
149
- }
150
-
151
134
  async createMemory(
152
135
  input: CreateMemoryInput & { embedding?: number[] }
153
136
  ): Promise<BaseMemoryType | undefined> {
154
137
  // Initialize storage for this roomId if needed
155
138
  await this.initializeStorage(input.roomId);
156
139
 
157
- // Search for existing memory with same data and query
158
- const searchResults = await this.search(input.data, input.roomId, {
159
- limit: 1,
160
- });
161
- const existingMemory = searchResults.find(
162
- (result) =>
163
- result.document.data === input.data &&
164
- result.document.query === input.query &&
165
- result.document.roomId === input.roomId
166
- );
167
-
168
- // If found, return existing memory
169
- if (existingMemory) {
170
- return existingMemory.document;
171
- }
172
-
173
140
  // If not found, create new memory
174
141
  const memory: BaseMemoryType = {
175
- id: crypto.randomUUID(),
142
+ id: input.id || crypto.randomUUID(),
176
143
  data: input.data,
177
- query: input.query,
178
144
  embedding: input.embedding || null,
179
145
  roomId: input.roomId,
180
146
  createdAt: new Date(),
@@ -196,7 +162,6 @@ export class MeilisearchAdapter extends BaseMemory {
196
162
  ? {
197
163
  id: result.id,
198
164
  data: result.data,
199
- query: result.query,
200
165
  embedding: result.embedding,
201
166
  roomId: result.roomId,
202
167
  createdAt: result.createdAt,
@@ -219,7 +184,6 @@ export class MeilisearchAdapter extends BaseMemory {
219
184
  .map((result) => ({
220
185
  id: result.document.id,
221
186
  data: result.document.data,
222
- query: result.document.query,
223
187
  embedding: result.document.embedding,
224
188
  roomId: result.document.roomId,
225
189
  createdAt: result.document.createdAt,
@@ -228,10 +192,13 @@ export class MeilisearchAdapter extends BaseMemory {
228
192
 
229
193
  async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
230
194
  const results = await this.makeRequest(`/indexes/${roomId}/documents`);
231
- return results.map((doc: any) => ({
195
+ if (results.total === 0) {
196
+ return [];
197
+ }
198
+
199
+ return results.results.map((doc: any) => ({
232
200
  id: doc.id,
233
201
  data: doc.data,
234
- query: doc.query,
235
202
  embedding: doc.embedding,
236
203
  roomId: doc.roomId,
237
204
  createdAt: doc.createdAt,
@@ -269,9 +236,6 @@ export class MeilisearchAdapter extends BaseMemory {
269
236
  for (const index of indexes) {
270
237
  await this.deleteStorage(index.uid);
271
238
  }
272
-
273
- // Reinitialize the default index
274
- await this.init();
275
239
  } catch (error) {
276
240
  const errorMessage =
277
241
  error instanceof Error ? error.message : "Unknown error";
@@ -281,6 +245,7 @@ export class MeilisearchAdapter extends BaseMemory {
281
245
  }
282
246
 
283
247
  interface SearchResult {
284
- document: BaseMemoryType;
285
- score: number;
248
+ document?: any;
249
+ score?: number;
250
+ results?: any[];
286
251
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai.ntellect/core",
3
- "version": "0.6.11",
3
+ "version": "0.6.13",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -35,7 +35,7 @@
35
35
  "@types/sinon": "^17.0.3",
36
36
  "@types/ws": "^8.5.14",
37
37
  "chai": "^4.5.0",
38
- "dotenv": "^16.4.5",
38
+ "dotenv": "^16.4.7",
39
39
  "meilisearch": "^0.37.0",
40
40
  "mocha": "^10.0.0",
41
41
  "redis": "^4.6.13",
package/tsconfig.json CHANGED
@@ -12,5 +12,5 @@
12
12
  },
13
13
  "outDir": "./dist"
14
14
  },
15
- "exclude": ["node_modules", "examples", "test"]
15
+ "exclude": ["node_modules", "examples", "test", "app"]
16
16
  }
package/types/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z, ZodSchema } from "zod";
2
2
 
3
3
  /* ======================== MEMORY ======================== */
4
4
 
@@ -11,8 +11,9 @@ import { z } from "zod";
11
11
  * @property {number} [ttl] - Time-to-live in seconds (optional).
12
12
  */
13
13
  export type CreateMemoryInput = {
14
- query: string;
14
+ id?: string;
15
15
  data: any;
16
+ embedding?: number[];
16
17
  roomId: string;
17
18
  ttl?: number;
18
19
  };
@@ -29,8 +30,7 @@ export type CreateMemoryInput = {
29
30
  */
30
31
  export type BaseMemoryType = {
31
32
  id: string;
32
- data: string;
33
- query: string;
33
+ data: any;
34
34
  embedding: number[] | null;
35
35
  roomId: string;
36
36
  createdAt: Date;
@@ -172,19 +172,39 @@ export type ScheduledRequest = {
172
172
 
173
173
  /* ======================== GRAPH ======================== */
174
174
 
175
- /**
176
- * Defines a graph definition.
177
- * @typedef {Object} GraphDefinition
178
- * @property {string} name - The graph name.
179
- * @property {string} entryNode - The entry node name.
180
- * @property {Record<string, Node<T>>} nodes - The nodes in the graph.
181
- * @property {z.ZodSchema<T>} [schema] - Optional schema for input validation.
182
- */
183
- export type GraphDefinition<T> = {
175
+ export type GraphContext<T extends ZodSchema> = z.infer<T>;
176
+
177
+ export type Node<T extends ZodSchema, P extends ZodSchema = ZodSchema> = {
178
+ name: string;
179
+ execute?: (context: GraphContext<T>) => Promise<void>;
180
+ executeWithParams?: (
181
+ context: GraphContext<T>,
182
+ params: z.infer<P>
183
+ ) => Promise<void>; // ✅ Nouvelle méthode
184
+ next?: string[];
185
+ condition?: (context: GraphContext<T>) => boolean;
186
+ onError?: (error: Error) => void;
187
+ events?: string[];
188
+ schema?: T;
189
+ parameters?: P; // ✅ Ajout d'un schéma spécifique aux paramètres du nœud
190
+ retry?: {
191
+ maxAttempts: number;
192
+ delay: number;
193
+ };
194
+ };
195
+
196
+ export type GraphConfig<T extends ZodSchema> = {
197
+ name: string;
198
+ nodes: Node<T>[];
199
+ initialContext?: GraphContext<T>;
200
+ validator?: T;
201
+ globalErrorHandler?: (error: Error, context: GraphContext<T>) => void;
202
+ };
203
+
204
+ export type GraphDefinition<T extends ZodSchema> = {
184
205
  name: string;
185
- entryNode: string;
186
206
  nodes: Record<string, Node<T>>;
187
- schema?: z.ZodSchema<T>;
207
+ entryNode: string;
188
208
  };
189
209
 
190
210
  /**
@@ -194,29 +214,6 @@ export type GraphDefinition<T> = {
194
214
  */
195
215
  export type SharedState<T> = T;
196
216
 
197
- /**
198
- * Defines a graph node within a graph execution structure.
199
- * @typedef {Object} Node
200
- * @property {string} name - The node name.
201
- * @property {string} [description] - Optional description.
202
- * @property {(params: P, state: SharedState<T>) => Promise<SharedState<T> | void>} execute - Execution function.
203
- * @property {(state: SharedState<T>) => boolean} [condition] - Optional condition for execution.
204
- * @property {NodeRelationship[]} [relationships] - Possible node transitions.
205
- * @property {z.ZodSchema<P>} [schema] - Optional schema for input validation.
206
- * @property {any} [state] - Internal node state.
207
- * @property {string[]} [events] - Events triggered by the node.
208
- */
209
- export type Node<T, P = any> = {
210
- name: string;
211
- description?: string;
212
- execute: (state: SharedState<T>) => Promise<SharedState<T> | void>;
213
- condition?: (state: SharedState<T>) => boolean;
214
- relationships?: NodeRelationship[];
215
- schema?: z.ZodSchema<P>;
216
- state?: any;
217
- events?: string[];
218
- };
219
-
220
217
  /**
221
218
  * Defines a node relationship in an execution graph.
222
219
  * @typedef {Object} NodeRelationship
@@ -0,0 +1,170 @@
1
+ import { MeilisearchAdapter } from "@/memory/adapters/meilisearch";
2
+ import { AIEmbeddingService } from "@/services/embedding";
3
+ import { openai } from "@ai-sdk/openai";
4
+ import { generateObject } from "ai";
5
+ import { z } from "zod";
6
+
7
+ export const experimentalGraphRag = async (context: {
8
+ prompt: string;
9
+ results: any;
10
+ }) => {
11
+ if (!process.env.MEILISEARCH_API_KEY)
12
+ throw new Error("MEILISEARCH_API_KEY is not set");
13
+ if (!process.env.MEILISEARCH_HOST)
14
+ throw new Error("MEILISEARCH_HOST is not set");
15
+
16
+ const memoryManager = new MeilisearchAdapter({
17
+ apiKey: process.env.MEILISEARCH_API_KEY,
18
+ host: process.env.MEILISEARCH_HOST,
19
+ });
20
+ await memoryManager.init("nodes");
21
+ await memoryManager.init("edges");
22
+ const { existingNodes } = await retrieveExistingRelations(
23
+ memoryManager,
24
+ "nodes"
25
+ );
26
+ const prompt = `
27
+ User asked: ${context.prompt}
28
+ Results: ${JSON.stringify(context.results, null, 2)}
29
+ Existing nodes: ${JSON.stringify(existingNodes, null, 2)}
30
+ `;
31
+ console.log("🔍 Prompt:", prompt);
32
+ const llmMemory = await generateObject({
33
+ model: openai("gpt-4o"),
34
+ prompt,
35
+ schema: z.object({
36
+ nodes: z.array(
37
+ z.object({
38
+ name: z.string(), // Nom de l'entité (ex: Adresse, ETH, Transaction ID)
39
+ metadata: z.record(z.string(), z.any()), // Métadonnées associées
40
+ })
41
+ ),
42
+ edges: z.array(
43
+ z.object({
44
+ source: z.string(), // ID de l'entité source
45
+ target: z.string(), // ID de l'entité cible
46
+ relation: z.string(), // Type de relation (ex: "sent", "received", "on_chain")
47
+ })
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
+
82
+ console.log("🔍 LLM memory (graph-based):");
83
+ console.log("Nodes:");
84
+ console.dir(llmMemory.object.nodes, { depth: null, colors: true });
85
+ console.log("Edges:");
86
+ console.dir(llmMemory.object.edges, { depth: null, colors: true });
87
+
88
+ const embeddingManager = new AIEmbeddingService(
89
+ openai.embedding("text-embedding-3-small")
90
+ );
91
+ const embedding = await embeddingManager.embedText(context.prompt);
92
+ let nodesNameToId: Record<string, string> = {};
93
+ for (const node of llmMemory.object.nodes) {
94
+ // Search for existing memory with same data and query
95
+ const searchResults = await memoryManager.search(node.name, "nodes", {
96
+ limit: 1,
97
+ });
98
+ const existingMemory = searchResults.find(
99
+ (result) =>
100
+ result.document.data.name === node.name &&
101
+ result.document.roomId === "nodes"
102
+ );
103
+
104
+ // If found, return existing memory
105
+ if (existingMemory) {
106
+ nodesNameToId[node.name] = existingMemory.document.id;
107
+ } else {
108
+ const nodesMemory = await memoryManager.createMemory({
109
+ data: node,
110
+ embedding,
111
+ roomId: "nodes",
112
+ });
113
+ nodesNameToId[node.name] = nodesMemory?.id || "";
114
+ }
115
+ }
116
+ for (const edge of llmMemory.object.edges) {
117
+ // Verify if source and target already exist in memory
118
+ const searchResults = await memoryManager.search(
119
+ nodesNameToId[edge.source],
120
+ "edges",
121
+ {
122
+ limit: 100,
123
+ }
124
+ );
125
+ const existingEdge = searchResults.find(
126
+ (result) =>
127
+ result.document.data.source === nodesNameToId[edge.source] &&
128
+ result.document.data.target === nodesNameToId[edge.target] &&
129
+ result.document.data.relation === edge.relation
130
+ );
131
+ if (existingEdge) {
132
+ } else {
133
+ await memoryManager.createMemory({
134
+ data: {
135
+ source: nodesNameToId[edge.source],
136
+ target: nodesNameToId[edge.target],
137
+ relation: edge.relation,
138
+ },
139
+ embedding,
140
+ roomId: "edges",
141
+ });
142
+ }
143
+ }
144
+ };
145
+
146
+ async function retrieveExistingRelations(
147
+ memoryManager: MeilisearchAdapter,
148
+ roomId: string
149
+ ) {
150
+ const existingNodesMemories = await memoryManager.getAllMemories("nodes");
151
+ const existingEdgesMemories = await memoryManager.getAllMemories("edges");
152
+ let existingNodes: any[] = [];
153
+ let existingEdges: any[] = [];
154
+
155
+ if (existingNodesMemories.length > 0) {
156
+ existingNodes = existingNodesMemories.flatMap((memory) => {
157
+ return {
158
+ id: memory.id,
159
+ data: memory.data,
160
+ };
161
+ });
162
+ }
163
+ if (existingEdgesMemories.length > 0) {
164
+ existingEdges = existingEdgesMemories.flatMap(
165
+ (memory) => memory.data || []
166
+ );
167
+ }
168
+
169
+ return { existingNodes, existingEdges };
170
+ }
@@ -1,18 +1,18 @@
1
- import { Node } from "@/types";
2
1
  import { z } from "zod";
2
+ import { Node } from "../types";
3
3
 
4
- export const stringifyZodSchema = <T>(nodes: Node<T>[]) => {
4
+ export const stringifyZodSchema = (nodes: Node<any>[]) => {
5
5
  return nodes
6
6
  .map((node) => {
7
- const schemaStr = node.schema
8
- ? getSchemaString(node.schema)
7
+ const schemaStr = node.parameters
8
+ ? getSchemaString(node.parameters)
9
9
  : "No parameters";
10
- return `Workflow: ${node.name}\nDescription: ${node.description}\nParameters: ${schemaStr}`;
10
+ return `Workflow: ${node.name}\nParameters: ${schemaStr}`;
11
11
  })
12
12
  .join("\n\n");
13
13
  };
14
14
 
15
- const getSchemaString = (schema: z.ZodType): string => {
15
+ export const getSchemaString = (schema: z.ZodType): string => {
16
16
  if (schema instanceof z.ZodObject) {
17
17
  const entries = Object.entries(schema.shape);
18
18
  const fields = entries.map(([key, value]) => {