@ai.ntellect/core 0.6.16 → 0.6.19
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/.mocharc.json +1 -2
- package/README.md +123 -178
- package/dist/graph/controller.js +29 -6
- package/dist/graph/index.js +402 -0
- package/dist/index.js +22 -7
- package/dist/interfaces/index.js +15 -0
- package/dist/modules/agenda/adapters/node-cron/index.js +29 -0
- package/dist/modules/agenda/index.js +140 -0
- package/dist/{services/embedding.js → modules/embedding/adapters/ai/index.js} +24 -7
- package/dist/modules/embedding/index.js +59 -0
- package/dist/modules/memory/adapters/in-memory/index.js +210 -0
- package/dist/{memory → modules/memory}/adapters/meilisearch/index.js +97 -2
- package/dist/{memory → modules/memory}/adapters/redis/index.js +77 -15
- package/dist/modules/memory/index.js +103 -0
- package/dist/utils/{stringifiy-zod-schema.js → generate-action-schema.js} +5 -5
- package/graph/controller.ts +38 -14
- package/graph/index.ts +468 -0
- package/index.ts +25 -7
- package/interfaces/index.ts +346 -28
- package/modules/agenda/adapters/node-cron/index.ts +25 -0
- package/modules/agenda/index.ts +159 -0
- package/modules/embedding/adapters/ai/index.ts +42 -0
- package/modules/embedding/index.ts +45 -0
- package/modules/memory/adapters/in-memory/index.ts +203 -0
- package/{memory → modules/memory}/adapters/meilisearch/index.ts +114 -8
- package/modules/memory/adapters/redis/index.ts +164 -0
- package/modules/memory/index.ts +93 -0
- package/package.json +4 -4
- package/test/graph/index.test.ts +646 -0
- package/test/modules/agenda/node-cron.test.ts +286 -0
- package/test/modules/embedding/ai.test.ts +78 -0
- package/test/modules/memory/adapters/in-memory.test.ts +153 -0
- package/test/{memory → modules/memory}/adapters/meilisearch.test.ts +80 -94
- package/test/modules/memory/adapters/redis.test.ts +169 -0
- package/test/modules/memory/base.test.ts +230 -0
- package/test/services/agenda.test.ts +279 -280
- package/tsconfig.json +0 -3
- package/types/index.ts +82 -203
- package/utils/{stringifiy-zod-schema.ts → generate-action-schema.ts} +3 -3
- package/app/README.md +0 -36
- package/app/app/favicon.ico +0 -0
- package/app/app/globals.css +0 -21
- package/app/app/gun.ts +0 -0
- package/app/app/layout.tsx +0 -18
- package/app/app/page.tsx +0 -321
- package/app/eslint.config.mjs +0 -16
- package/app/next.config.ts +0 -7
- package/app/package-lock.json +0 -5912
- package/app/package.json +0 -31
- package/app/pnpm-lock.yaml +0 -4031
- package/app/postcss.config.mjs +0 -8
- package/app/public/file.svg +0 -1
- package/app/public/globe.svg +0 -1
- package/app/public/next.svg +0 -1
- package/app/public/vercel.svg +0 -1
- package/app/public/window.svg +0 -1
- package/app/tailwind.config.ts +0 -18
- package/app/tsconfig.json +0 -27
- package/dist/graph/graph.js +0 -162
- package/dist/memory/index.js +0 -9
- package/dist/services/agenda.js +0 -115
- package/dist/services/queue.js +0 -142
- package/dist/utils/experimental-graph-rag.js +0 -152
- package/dist/utils/generate-object.js +0 -111
- package/dist/utils/inject-actions.js +0 -16
- package/dist/utils/queue-item-transformer.js +0 -24
- package/dist/utils/sanitize-results.js +0 -60
- package/graph/graph.ts +0 -193
- package/memory/adapters/redis/index.ts +0 -103
- package/memory/index.ts +0 -22
- package/services/agenda.ts +0 -118
- package/services/embedding.ts +0 -26
- package/services/queue.ts +0 -145
- package/test/.env.test +0 -4
- package/test/graph/engine.test.ts +0 -533
- package/test/memory/adapters/redis.test.ts +0 -160
- package/test/memory/base.test.ts +0 -229
- package/test/services/queue.test.ts +0 -286
- package/utils/experimental-graph-rag.ts +0 -170
- package/utils/generate-object.ts +0 -117
- package/utils/inject-actions.ts +0 -19
- package/utils/queue-item-transformer.ts +0 -38
- package/utils/sanitize-results.ts +0 -66
@@ -1,170 +0,0 @@
|
|
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
|
-
}
|
package/utils/generate-object.ts
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
import { CoreMessage, LanguageModelV1, generateText } from "ai";
|
2
|
-
import { z } from "zod";
|
3
|
-
|
4
|
-
export const describeZodSchema = (schema: z.ZodType): string => {
|
5
|
-
if (schema instanceof z.ZodObject) {
|
6
|
-
const entries = Object.entries(schema.shape);
|
7
|
-
const fields = entries.map(([key, value]) => {
|
8
|
-
const description = (value as any)._def.description || "";
|
9
|
-
const fieldSchema = describeZodSchema(value as z.ZodType);
|
10
|
-
return description
|
11
|
-
? `${key}: ${fieldSchema} // ${description}`
|
12
|
-
: `${key}: ${fieldSchema}`;
|
13
|
-
});
|
14
|
-
return `z.object({${fields.join(", ")}})`;
|
15
|
-
}
|
16
|
-
|
17
|
-
if (schema instanceof z.ZodArray) {
|
18
|
-
return `z.array(${describeZodSchema(schema.element)})`;
|
19
|
-
}
|
20
|
-
|
21
|
-
if (schema instanceof z.ZodString) {
|
22
|
-
return "z.string()";
|
23
|
-
}
|
24
|
-
|
25
|
-
if (schema instanceof z.ZodNumber) {
|
26
|
-
return "z.number()";
|
27
|
-
}
|
28
|
-
|
29
|
-
if (schema instanceof z.ZodBoolean) {
|
30
|
-
return "z.boolean()";
|
31
|
-
}
|
32
|
-
|
33
|
-
if (schema instanceof z.ZodOptional) {
|
34
|
-
return `z.optional(${describeZodSchema(schema._def.innerType)})`;
|
35
|
-
}
|
36
|
-
|
37
|
-
if (schema instanceof z.ZodUnion) {
|
38
|
-
return `z.union([${schema._def.options
|
39
|
-
.map((option: z.ZodType) => describeZodSchema(option))
|
40
|
-
.join(", ")}])`;
|
41
|
-
}
|
42
|
-
|
43
|
-
if (schema instanceof z.ZodEnum) {
|
44
|
-
return `z.enum(${JSON.stringify(schema._def.values)})`;
|
45
|
-
}
|
46
|
-
|
47
|
-
if (schema instanceof z.ZodLiteral) {
|
48
|
-
return `z.literal(${JSON.stringify(schema._def.value)})`;
|
49
|
-
}
|
50
|
-
|
51
|
-
return "z.unknown()"; // Fallback for unknown types
|
52
|
-
};
|
53
|
-
|
54
|
-
export const generateObject = async <T>(config: {
|
55
|
-
model: LanguageModelV1;
|
56
|
-
schema: z.ZodSchema;
|
57
|
-
system: string;
|
58
|
-
temperature: number;
|
59
|
-
prompt?: string;
|
60
|
-
messages?: CoreMessage[];
|
61
|
-
}): Promise<{ object: T }> => {
|
62
|
-
// Generate a detailed description of the schema
|
63
|
-
const schemaDescription = describeZodSchema(config.schema);
|
64
|
-
|
65
|
-
const baseContext = `
|
66
|
-
${config.system}
|
67
|
-
EXPECTED SCHEMA:
|
68
|
-
${schemaDescription}
|
69
|
-
|
70
|
-
BAD EXAMPLE:
|
71
|
-
\`\`\`json
|
72
|
-
{
|
73
|
-
"key": "value"
|
74
|
-
}
|
75
|
-
\`\`\`
|
76
|
-
|
77
|
-
GOOD EXAMPLE:
|
78
|
-
{
|
79
|
-
"key": "value"
|
80
|
-
}
|
81
|
-
|
82
|
-
OUTPUT ONLY THE JSON SCHEMA, NO 'TRIPLE QUOTES'JSON OR ANY OTHER TEXT. ONLY THE JSON SCHEMA.
|
83
|
-
`;
|
84
|
-
|
85
|
-
console.log("🔍 Generating object with context:");
|
86
|
-
console.log(`${config.prompt}\n${baseContext}\n`);
|
87
|
-
const response = await generateText({
|
88
|
-
model: config.model,
|
89
|
-
messages: !config.prompt
|
90
|
-
? [
|
91
|
-
{
|
92
|
-
role: "system",
|
93
|
-
content: baseContext,
|
94
|
-
},
|
95
|
-
...(config.messages ?? []),
|
96
|
-
]
|
97
|
-
: undefined,
|
98
|
-
system: config.system,
|
99
|
-
temperature: config.temperature,
|
100
|
-
prompt: !config.prompt ? undefined : `${config.prompt}\n\n${baseContext}`,
|
101
|
-
});
|
102
|
-
|
103
|
-
try {
|
104
|
-
// Clean the response text from any markdown or code block markers
|
105
|
-
const cleanText = response.text
|
106
|
-
.replace(/```json\s*/g, "")
|
107
|
-
.replace(/```\s*$/g, "")
|
108
|
-
.trim();
|
109
|
-
|
110
|
-
const parsedResponse = JSON.parse(cleanText);
|
111
|
-
const validatedResponse = config.schema.parse(parsedResponse);
|
112
|
-
return { object: validatedResponse as T };
|
113
|
-
} catch (error) {
|
114
|
-
console.error("Error parsing or validating JSON response:", error);
|
115
|
-
throw new Error("Failed to generate valid JSON response");
|
116
|
-
}
|
117
|
-
};
|
package/utils/inject-actions.ts
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
import { z } from "zod";
|
2
|
-
import { ActionSchema } from "../types";
|
3
|
-
|
4
|
-
export const injectActions = (actions: ActionSchema[]) => {
|
5
|
-
return actions.map((action) => {
|
6
|
-
const parameters = action.parameters as z.ZodObject<any>;
|
7
|
-
const schemaShape = Object.keys(parameters._def.shape()).join(", ");
|
8
|
-
const actionString = `* ${action.name}( { ${schemaShape} }) (${
|
9
|
-
action.description
|
10
|
-
}) ${
|
11
|
-
action.examples
|
12
|
-
? `Eg: ${action.examples.map((example: any) => {
|
13
|
-
return JSON.stringify(example);
|
14
|
-
})}`
|
15
|
-
: ""
|
16
|
-
}`;
|
17
|
-
return actionString;
|
18
|
-
});
|
19
|
-
};
|
@@ -1,38 +0,0 @@
|
|
1
|
-
import { QueueItem, QueueItemParameter, QueueResult } from "@/types";
|
2
|
-
|
3
|
-
export class QueueItemTransformer {
|
4
|
-
static transformActionToQueueItem(action: {
|
5
|
-
name: string;
|
6
|
-
parameters: Record<string, any>;
|
7
|
-
}): QueueItem {
|
8
|
-
return {
|
9
|
-
name: action.name || "",
|
10
|
-
parameters: QueueItemTransformer.transformParameters(
|
11
|
-
action.parameters || {}
|
12
|
-
),
|
13
|
-
};
|
14
|
-
}
|
15
|
-
|
16
|
-
static transformFromSimilarActions(
|
17
|
-
similarActions: QueueResult[]
|
18
|
-
): QueueItem[] | undefined {
|
19
|
-
return similarActions?.map((action: QueueResult) =>
|
20
|
-
QueueItemTransformer.transformActionToQueueItem(action)
|
21
|
-
);
|
22
|
-
}
|
23
|
-
|
24
|
-
private static transformParameters(
|
25
|
-
parameters: Record<string, any>
|
26
|
-
): QueueItemParameter[] {
|
27
|
-
return Object.entries(parameters).map(([name, value]) => ({
|
28
|
-
name,
|
29
|
-
value: typeof value === "object" ? JSON.stringify(value) : String(value),
|
30
|
-
}));
|
31
|
-
}
|
32
|
-
|
33
|
-
static transformActionsToQueueItems(
|
34
|
-
actions: { name: string; parameters: Record<string, any> }[] | undefined
|
35
|
-
): QueueItem[] | undefined {
|
36
|
-
return actions?.map((action) => this.transformActionToQueueItem(action));
|
37
|
-
}
|
38
|
-
}
|
@@ -1,66 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Utility class to sanitize JSON results for evaluation
|
3
|
-
*/
|
4
|
-
export class ResultSanitizer {
|
5
|
-
/**
|
6
|
-
* Sanitizes JSON results by removing special characters and formatting
|
7
|
-
* @param results - The results to sanitize
|
8
|
-
* @returns Sanitized string
|
9
|
-
*/
|
10
|
-
static sanitize(results: any): string {
|
11
|
-
if (!results) return "";
|
12
|
-
|
13
|
-
try {
|
14
|
-
const jsonString = JSON.stringify(results);
|
15
|
-
return (
|
16
|
-
jsonString
|
17
|
-
// Basic cleanup
|
18
|
-
.replace(/\\n/g, " ") // Remove newlines
|
19
|
-
.replace(/\s+/g, " ") // Remove extra spaces
|
20
|
-
.replace(/\\"/g, '"') // Fix escaped quotes
|
21
|
-
.replace(/\\+/g, "") // Remove extra backslashes
|
22
|
-
|
23
|
-
// Remove unnecessary quotes around objects and arrays
|
24
|
-
.replace(/"\[/g, "[") // Remove quotes around arrays start
|
25
|
-
.replace(/\]"/g, "]") // Remove quotes around arrays end
|
26
|
-
.replace(/"{/g, "{") // Remove quotes around objects start
|
27
|
-
.replace(/}"/g, "}") // Remove quotes around objects end
|
28
|
-
|
29
|
-
// Clean up numbers and values
|
30
|
-
.replace(/"(\d+\.?\d*)"/g, "$1") // Remove quotes around numbers
|
31
|
-
.replace(/:\s*"(true|false|null)"/g, ": $1") // Remove quotes around booleans and null
|
32
|
-
|
33
|
-
// Clean up URLs and content
|
34
|
-
.replace(
|
35
|
-
/(?<=content":")([^"]+)(?=")/g,
|
36
|
-
(match) => match.trim().replace(/\s+/g, " ") // Clean content spacing
|
37
|
-
)
|
38
|
-
.replace(
|
39
|
-
/(?<=link":")([^"]+)(?=")/g,
|
40
|
-
(match) => match.replace(/&/g, "&") // Fix URL encodings
|
41
|
-
)
|
42
|
-
|
43
|
-
// Final cleanup
|
44
|
-
.replace(/,\s*([}\]])/g, "$1") // Remove trailing commas
|
45
|
-
.replace(/:\s+/g, ":") // Remove spaces after colons
|
46
|
-
.replace(/,\s+/g, ",") // Remove spaces after commas
|
47
|
-
.trim()
|
48
|
-
); // Remove leading/trailing whitespace
|
49
|
-
} catch (error) {
|
50
|
-
console.error("Error sanitizing results:", error);
|
51
|
-
return String(results);
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
/**
|
56
|
-
* Formats numbers to a consistent format
|
57
|
-
* @param value - The number to format
|
58
|
-
* @returns Formatted number string
|
59
|
-
*/
|
60
|
-
private static formatNumber(value: number): string {
|
61
|
-
return value.toLocaleString("en-US", {
|
62
|
-
maximumFractionDigits: 2,
|
63
|
-
useGrouping: false,
|
64
|
-
});
|
65
|
-
}
|
66
|
-
}
|