@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,111 +0,0 @@
|
|
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.generateObject = exports.describeZodSchema = void 0;
|
13
|
-
const ai_1 = require("ai");
|
14
|
-
const zod_1 = require("zod");
|
15
|
-
const describeZodSchema = (schema) => {
|
16
|
-
if (schema instanceof zod_1.z.ZodObject) {
|
17
|
-
const entries = Object.entries(schema.shape);
|
18
|
-
const fields = entries.map(([key, value]) => {
|
19
|
-
const description = value._def.description || "";
|
20
|
-
const fieldSchema = (0, exports.describeZodSchema)(value);
|
21
|
-
return description
|
22
|
-
? `${key}: ${fieldSchema} // ${description}`
|
23
|
-
: `${key}: ${fieldSchema}`;
|
24
|
-
});
|
25
|
-
return `z.object({${fields.join(", ")}})`;
|
26
|
-
}
|
27
|
-
if (schema instanceof zod_1.z.ZodArray) {
|
28
|
-
return `z.array(${(0, exports.describeZodSchema)(schema.element)})`;
|
29
|
-
}
|
30
|
-
if (schema instanceof zod_1.z.ZodString) {
|
31
|
-
return "z.string()";
|
32
|
-
}
|
33
|
-
if (schema instanceof zod_1.z.ZodNumber) {
|
34
|
-
return "z.number()";
|
35
|
-
}
|
36
|
-
if (schema instanceof zod_1.z.ZodBoolean) {
|
37
|
-
return "z.boolean()";
|
38
|
-
}
|
39
|
-
if (schema instanceof zod_1.z.ZodOptional) {
|
40
|
-
return `z.optional(${(0, exports.describeZodSchema)(schema._def.innerType)})`;
|
41
|
-
}
|
42
|
-
if (schema instanceof zod_1.z.ZodUnion) {
|
43
|
-
return `z.union([${schema._def.options
|
44
|
-
.map((option) => (0, exports.describeZodSchema)(option))
|
45
|
-
.join(", ")}])`;
|
46
|
-
}
|
47
|
-
if (schema instanceof zod_1.z.ZodEnum) {
|
48
|
-
return `z.enum(${JSON.stringify(schema._def.values)})`;
|
49
|
-
}
|
50
|
-
if (schema instanceof zod_1.z.ZodLiteral) {
|
51
|
-
return `z.literal(${JSON.stringify(schema._def.value)})`;
|
52
|
-
}
|
53
|
-
return "z.unknown()"; // Fallback for unknown types
|
54
|
-
};
|
55
|
-
exports.describeZodSchema = describeZodSchema;
|
56
|
-
const generateObject = (config) => __awaiter(void 0, void 0, void 0, function* () {
|
57
|
-
var _a;
|
58
|
-
// Generate a detailed description of the schema
|
59
|
-
const schemaDescription = (0, exports.describeZodSchema)(config.schema);
|
60
|
-
const baseContext = `
|
61
|
-
${config.system}
|
62
|
-
EXPECTED SCHEMA:
|
63
|
-
${schemaDescription}
|
64
|
-
|
65
|
-
BAD EXAMPLE:
|
66
|
-
\`\`\`json
|
67
|
-
{
|
68
|
-
"key": "value"
|
69
|
-
}
|
70
|
-
\`\`\`
|
71
|
-
|
72
|
-
GOOD EXAMPLE:
|
73
|
-
{
|
74
|
-
"key": "value"
|
75
|
-
}
|
76
|
-
|
77
|
-
OUTPUT ONLY THE JSON SCHEMA, NO 'TRIPLE QUOTES'JSON OR ANY OTHER TEXT. ONLY THE JSON SCHEMA.
|
78
|
-
`;
|
79
|
-
console.log("🔍 Generating object with context:");
|
80
|
-
console.log(`${config.prompt}\n${baseContext}\n`);
|
81
|
-
const response = yield (0, ai_1.generateText)({
|
82
|
-
model: config.model,
|
83
|
-
messages: !config.prompt
|
84
|
-
? [
|
85
|
-
{
|
86
|
-
role: "system",
|
87
|
-
content: baseContext,
|
88
|
-
},
|
89
|
-
...((_a = config.messages) !== null && _a !== void 0 ? _a : []),
|
90
|
-
]
|
91
|
-
: undefined,
|
92
|
-
system: config.system,
|
93
|
-
temperature: config.temperature,
|
94
|
-
prompt: !config.prompt ? undefined : `${config.prompt}\n\n${baseContext}`,
|
95
|
-
});
|
96
|
-
try {
|
97
|
-
// Clean the response text from any markdown or code block markers
|
98
|
-
const cleanText = response.text
|
99
|
-
.replace(/```json\s*/g, "")
|
100
|
-
.replace(/```\s*$/g, "")
|
101
|
-
.trim();
|
102
|
-
const parsedResponse = JSON.parse(cleanText);
|
103
|
-
const validatedResponse = config.schema.parse(parsedResponse);
|
104
|
-
return { object: validatedResponse };
|
105
|
-
}
|
106
|
-
catch (error) {
|
107
|
-
console.error("Error parsing or validating JSON response:", error);
|
108
|
-
throw new Error("Failed to generate valid JSON response");
|
109
|
-
}
|
110
|
-
});
|
111
|
-
exports.generateObject = generateObject;
|
@@ -1,16 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.injectActions = void 0;
|
4
|
-
const injectActions = (actions) => {
|
5
|
-
return actions.map((action) => {
|
6
|
-
const parameters = action.parameters;
|
7
|
-
const schemaShape = Object.keys(parameters._def.shape()).join(", ");
|
8
|
-
const actionString = `* ${action.name}( { ${schemaShape} }) (${action.description}) ${action.examples
|
9
|
-
? `Eg: ${action.examples.map((example) => {
|
10
|
-
return JSON.stringify(example);
|
11
|
-
})}`
|
12
|
-
: ""}`;
|
13
|
-
return actionString;
|
14
|
-
});
|
15
|
-
};
|
16
|
-
exports.injectActions = injectActions;
|
@@ -1,24 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.QueueItemTransformer = void 0;
|
4
|
-
class QueueItemTransformer {
|
5
|
-
static transformActionToQueueItem(action) {
|
6
|
-
return {
|
7
|
-
name: action.name || "",
|
8
|
-
parameters: QueueItemTransformer.transformParameters(action.parameters || {}),
|
9
|
-
};
|
10
|
-
}
|
11
|
-
static transformFromSimilarActions(similarActions) {
|
12
|
-
return similarActions === null || similarActions === void 0 ? void 0 : similarActions.map((action) => QueueItemTransformer.transformActionToQueueItem(action));
|
13
|
-
}
|
14
|
-
static transformParameters(parameters) {
|
15
|
-
return Object.entries(parameters).map(([name, value]) => ({
|
16
|
-
name,
|
17
|
-
value: typeof value === "object" ? JSON.stringify(value) : String(value),
|
18
|
-
}));
|
19
|
-
}
|
20
|
-
static transformActionsToQueueItems(actions) {
|
21
|
-
return actions === null || actions === void 0 ? void 0 : actions.map((action) => this.transformActionToQueueItem(action));
|
22
|
-
}
|
23
|
-
}
|
24
|
-
exports.QueueItemTransformer = QueueItemTransformer;
|
@@ -1,60 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.ResultSanitizer = void 0;
|
4
|
-
/**
|
5
|
-
* Utility class to sanitize JSON results for evaluation
|
6
|
-
*/
|
7
|
-
class ResultSanitizer {
|
8
|
-
/**
|
9
|
-
* Sanitizes JSON results by removing special characters and formatting
|
10
|
-
* @param results - The results to sanitize
|
11
|
-
* @returns Sanitized string
|
12
|
-
*/
|
13
|
-
static sanitize(results) {
|
14
|
-
if (!results)
|
15
|
-
return "";
|
16
|
-
try {
|
17
|
-
const jsonString = JSON.stringify(results);
|
18
|
-
return (jsonString
|
19
|
-
// Basic cleanup
|
20
|
-
.replace(/\\n/g, " ") // Remove newlines
|
21
|
-
.replace(/\s+/g, " ") // Remove extra spaces
|
22
|
-
.replace(/\\"/g, '"') // Fix escaped quotes
|
23
|
-
.replace(/\\+/g, "") // Remove extra backslashes
|
24
|
-
// Remove unnecessary quotes around objects and arrays
|
25
|
-
.replace(/"\[/g, "[") // Remove quotes around arrays start
|
26
|
-
.replace(/\]"/g, "]") // Remove quotes around arrays end
|
27
|
-
.replace(/"{/g, "{") // Remove quotes around objects start
|
28
|
-
.replace(/}"/g, "}") // Remove quotes around objects end
|
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
|
-
// Clean up URLs and content
|
33
|
-
.replace(/(?<=content":")([^"]+)(?=")/g, (match) => match.trim().replace(/\s+/g, " ") // Clean content spacing
|
34
|
-
)
|
35
|
-
.replace(/(?<=link":")([^"]+)(?=")/g, (match) => match.replace(/&/g, "&") // Fix URL encodings
|
36
|
-
)
|
37
|
-
// Final cleanup
|
38
|
-
.replace(/,\s*([}\]])/g, "$1") // Remove trailing commas
|
39
|
-
.replace(/:\s+/g, ":") // Remove spaces after colons
|
40
|
-
.replace(/,\s+/g, ",") // Remove spaces after commas
|
41
|
-
.trim()); // Remove leading/trailing whitespace
|
42
|
-
}
|
43
|
-
catch (error) {
|
44
|
-
console.error("Error sanitizing results:", error);
|
45
|
-
return String(results);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
/**
|
49
|
-
* Formats numbers to a consistent format
|
50
|
-
* @param value - The number to format
|
51
|
-
* @returns Formatted number string
|
52
|
-
*/
|
53
|
-
static formatNumber(value) {
|
54
|
-
return value.toLocaleString("en-US", {
|
55
|
-
maximumFractionDigits: 2,
|
56
|
-
useGrouping: false,
|
57
|
-
});
|
58
|
-
}
|
59
|
-
}
|
60
|
-
exports.ResultSanitizer = ResultSanitizer;
|
package/graph/graph.ts
DELETED
@@ -1,193 +0,0 @@
|
|
1
|
-
import { GraphConfig, GraphContext, GraphDefinition, Node } from "@/types";
|
2
|
-
import EventEmitter from "events";
|
3
|
-
import { ZodSchema } from "zod";
|
4
|
-
|
5
|
-
export class Graph<T extends ZodSchema> {
|
6
|
-
private nodes: Map<string, Node<T>>;
|
7
|
-
private context: GraphContext<T>;
|
8
|
-
public validator?: T;
|
9
|
-
private eventEmitter: EventEmitter;
|
10
|
-
private globalErrorHandler?: (error: Error, context: GraphContext<T>) => void;
|
11
|
-
|
12
|
-
constructor(public name: string, config: GraphConfig<T>) {
|
13
|
-
this.nodes = new Map(config.nodes.map((node) => [node.name, node]));
|
14
|
-
this.context = config.initialContext || ({} as GraphContext<T>);
|
15
|
-
this.validator = config.validator;
|
16
|
-
this.globalErrorHandler = config.globalErrorHandler;
|
17
|
-
this.eventEmitter = new EventEmitter();
|
18
|
-
this.setupEventListeners();
|
19
|
-
}
|
20
|
-
|
21
|
-
private createNewContext(): GraphContext<T> {
|
22
|
-
return structuredClone(this.context);
|
23
|
-
}
|
24
|
-
|
25
|
-
private setupEventListeners(): void {
|
26
|
-
for (const node of this.nodes.values()) {
|
27
|
-
node.events?.forEach((event) => {
|
28
|
-
this.eventEmitter.on(event, async (data?: Partial<GraphContext<T>>) => {
|
29
|
-
const context = this.createNewContext();
|
30
|
-
if (data) Object.assign(context, data);
|
31
|
-
await this.executeNode(node.name, context);
|
32
|
-
});
|
33
|
-
});
|
34
|
-
}
|
35
|
-
}
|
36
|
-
private async executeNode(
|
37
|
-
nodeName: string,
|
38
|
-
context: GraphContext<T>,
|
39
|
-
params?: any
|
40
|
-
): Promise<void> {
|
41
|
-
const node = this.nodes.get(nodeName);
|
42
|
-
if (!node) throw new Error(`❌ Node ${nodeName} not found`);
|
43
|
-
|
44
|
-
if (node.condition && !node.condition(context)) return;
|
45
|
-
|
46
|
-
let attempts = 0;
|
47
|
-
const maxAttempts = node.retry?.maxAttempts || 1;
|
48
|
-
const delay = node.retry?.delay || 0;
|
49
|
-
|
50
|
-
while (attempts < maxAttempts) {
|
51
|
-
try {
|
52
|
-
let validatedParams;
|
53
|
-
|
54
|
-
// ✅ Si le nœud a un `parameters`, on valide `params` avant exécution
|
55
|
-
if (node.parameters) {
|
56
|
-
if (!params) {
|
57
|
-
throw new Error(
|
58
|
-
`❌ Paramètres requis pour le nœud "${nodeName}" mais reçus: ${params}`
|
59
|
-
);
|
60
|
-
}
|
61
|
-
validatedParams = node.parameters.parse(params);
|
62
|
-
}
|
63
|
-
|
64
|
-
this.eventEmitter.emit("nodeStarted", { name: nodeName, context });
|
65
|
-
if (node.execute) {
|
66
|
-
await node.execute(context);
|
67
|
-
} else if (node.executeWithParams) {
|
68
|
-
if (!validatedParams) {
|
69
|
-
throw new Error(
|
70
|
-
`❌ Paramètres invalides pour le nœud "${nodeName}"`
|
71
|
-
);
|
72
|
-
}
|
73
|
-
await node.executeWithParams(context, validatedParams);
|
74
|
-
}
|
75
|
-
|
76
|
-
this.validateContext(context);
|
77
|
-
|
78
|
-
this.eventEmitter.emit("nodeCompleted", { name: nodeName, context });
|
79
|
-
|
80
|
-
if (node.next) {
|
81
|
-
await Promise.all(
|
82
|
-
node.next.map((nextNode) => this.executeNode(nextNode, context))
|
83
|
-
);
|
84
|
-
}
|
85
|
-
return;
|
86
|
-
} catch (error) {
|
87
|
-
attempts++;
|
88
|
-
|
89
|
-
if (attempts >= maxAttempts) {
|
90
|
-
this.eventEmitter.emit("nodeError", { nodeName, error });
|
91
|
-
node.onError?.(error as Error);
|
92
|
-
this.globalErrorHandler?.(error as Error, context);
|
93
|
-
throw error;
|
94
|
-
}
|
95
|
-
|
96
|
-
console.warn(
|
97
|
-
`[Graph ${this.name}] Retry attempt ${attempts} for node ${nodeName}`,
|
98
|
-
{ error }
|
99
|
-
);
|
100
|
-
|
101
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
102
|
-
}
|
103
|
-
}
|
104
|
-
}
|
105
|
-
|
106
|
-
private validateContext(context: GraphContext<T>): void {
|
107
|
-
if (this.validator) {
|
108
|
-
this.validator.parse(context);
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
async execute(
|
113
|
-
startNode: string,
|
114
|
-
inputContext?: Partial<GraphContext<T>>,
|
115
|
-
inputParams?: any
|
116
|
-
): Promise<GraphContext<T>> {
|
117
|
-
const context = this.createNewContext();
|
118
|
-
if (inputContext) Object.assign(context, inputContext);
|
119
|
-
|
120
|
-
this.eventEmitter.emit("graphStarted", { name: this.name });
|
121
|
-
try {
|
122
|
-
await this.executeNode(startNode, context, inputParams);
|
123
|
-
this.eventEmitter.emit("graphCompleted", { name: this.name, context });
|
124
|
-
return context;
|
125
|
-
} catch (error) {
|
126
|
-
this.eventEmitter.emit("graphError", { name: this.name, error });
|
127
|
-
this.globalErrorHandler?.(error as Error, context); // Gestionnaire d'erreurs global
|
128
|
-
throw error;
|
129
|
-
}
|
130
|
-
}
|
131
|
-
|
132
|
-
emit(
|
133
|
-
eventName: string,
|
134
|
-
data?: Partial<GraphContext<T>>
|
135
|
-
): Promise<GraphContext<T>> {
|
136
|
-
return new Promise((resolve, reject) => {
|
137
|
-
if (data) Object.assign(this.context, data); // ✅ Met à jour le contexte global
|
138
|
-
|
139
|
-
this.eventEmitter.emit(eventName, this.context); // Utilise le contexte global
|
140
|
-
|
141
|
-
const eventNodes = Array.from(this.nodes.values()).filter((node) =>
|
142
|
-
node.events?.includes(eventName)
|
143
|
-
);
|
144
|
-
if (eventNodes.length === 0) return resolve(this.context);
|
145
|
-
|
146
|
-
Promise.all(
|
147
|
-
eventNodes.map(
|
148
|
-
(node) =>
|
149
|
-
new Promise<void>((resolve) => {
|
150
|
-
this.eventEmitter.once("nodeCompleted", ({ nodeName }) => {
|
151
|
-
if (nodeName === node.name) resolve();
|
152
|
-
});
|
153
|
-
})
|
154
|
-
)
|
155
|
-
)
|
156
|
-
.then(() => resolve(this.context))
|
157
|
-
.catch(reject);
|
158
|
-
});
|
159
|
-
}
|
160
|
-
|
161
|
-
on(eventName: string, handler: (...args: any[]) => void): void {
|
162
|
-
this.eventEmitter.on(eventName, handler);
|
163
|
-
}
|
164
|
-
|
165
|
-
loadDefinition(definition: GraphDefinition<T>): void {
|
166
|
-
this.nodes.clear();
|
167
|
-
Object.values(definition.nodes).forEach((node) =>
|
168
|
-
this.nodes.set(node.name, node)
|
169
|
-
);
|
170
|
-
this.setupEventListeners();
|
171
|
-
}
|
172
|
-
|
173
|
-
getContext(): GraphContext<T> {
|
174
|
-
return structuredClone(this.context);
|
175
|
-
}
|
176
|
-
|
177
|
-
log(message: string, data?: any): void {
|
178
|
-
console.log(`[Graph ${this.name}] ${message}`, data);
|
179
|
-
}
|
180
|
-
|
181
|
-
addNode(node: Node<T>): void {
|
182
|
-
this.nodes.set(node.name, node);
|
183
|
-
this.setupEventListeners();
|
184
|
-
}
|
185
|
-
|
186
|
-
removeNode(nodeName: string): void {
|
187
|
-
this.nodes.delete(nodeName);
|
188
|
-
}
|
189
|
-
|
190
|
-
getNodes(): Node<T>[] {
|
191
|
-
return Array.from(this.nodes.values());
|
192
|
-
}
|
193
|
-
}
|
@@ -1,103 +0,0 @@
|
|
1
|
-
import { BaseMemoryService } from "@/interfaces";
|
2
|
-
import { BaseMemoryType } from "@/types";
|
3
|
-
import { createClient } from "redis";
|
4
|
-
|
5
|
-
export class RedisAdapter implements BaseMemoryService {
|
6
|
-
private redis;
|
7
|
-
private readonly cachePrefix: string;
|
8
|
-
private readonly cacheTTL: number;
|
9
|
-
|
10
|
-
constructor(
|
11
|
-
private readonly redisUrl: string,
|
12
|
-
options: {
|
13
|
-
cachePrefix?: string;
|
14
|
-
cacheTTL?: number;
|
15
|
-
}
|
16
|
-
) {
|
17
|
-
this.cachePrefix = options.cachePrefix || "memory:";
|
18
|
-
this.cacheTTL = options.cacheTTL || 3600;
|
19
|
-
this.redis = createClient({
|
20
|
-
url: redisUrl,
|
21
|
-
socket: {
|
22
|
-
tls: true,
|
23
|
-
rejectUnauthorized: true,
|
24
|
-
},
|
25
|
-
});
|
26
|
-
}
|
27
|
-
|
28
|
-
async initializeConnection(): Promise<void> {
|
29
|
-
this.redis.on("error", (err) => console.error("Redis Client Error:", err));
|
30
|
-
await this.redis.connect();
|
31
|
-
}
|
32
|
-
|
33
|
-
async createMemory(memory: BaseMemoryType, ttl?: number): Promise<void> {
|
34
|
-
const key = memory.roomId
|
35
|
-
? `${this.cachePrefix}${memory.roomId}:${memory.id}`
|
36
|
-
: `${this.cachePrefix}${memory.id}`;
|
37
|
-
|
38
|
-
await this.redis.set(key, JSON.stringify(memory), {
|
39
|
-
EX: ttl || this.cacheTTL,
|
40
|
-
});
|
41
|
-
}
|
42
|
-
|
43
|
-
async getMemoryById(
|
44
|
-
id: string,
|
45
|
-
roomId?: string
|
46
|
-
): Promise<BaseMemoryType | null> {
|
47
|
-
const key = roomId
|
48
|
-
? `${this.cachePrefix}${roomId}:${id}`
|
49
|
-
: `${this.cachePrefix}${id}`;
|
50
|
-
|
51
|
-
const data = await this.redis.get(key);
|
52
|
-
return data ? JSON.parse(data) : null;
|
53
|
-
}
|
54
|
-
|
55
|
-
async getMemoryByIndex(
|
56
|
-
query: string,
|
57
|
-
options: {
|
58
|
-
roomId?: string;
|
59
|
-
limit?: number;
|
60
|
-
} = {}
|
61
|
-
): Promise<BaseMemoryType[]> {
|
62
|
-
const pattern = options.roomId
|
63
|
-
? `${this.cachePrefix}${options.roomId}:*`
|
64
|
-
: `${this.cachePrefix}*`;
|
65
|
-
|
66
|
-
const keys = await this.redis.keys(pattern);
|
67
|
-
const memories = await Promise.all(
|
68
|
-
keys.map(async (key) => {
|
69
|
-
const data = await this.redis.get(key);
|
70
|
-
return data ? JSON.parse(data) : null;
|
71
|
-
})
|
72
|
-
);
|
73
|
-
return memories.filter(Boolean).slice(0, options.limit || 10);
|
74
|
-
}
|
75
|
-
|
76
|
-
async getAllMemories(): Promise<BaseMemoryType[]> {
|
77
|
-
const keys = await this.redis.keys(`${this.cachePrefix}*`);
|
78
|
-
const memories = await Promise.all(
|
79
|
-
keys.map(async (key) => {
|
80
|
-
const data = await this.redis.get(key);
|
81
|
-
return data ? JSON.parse(data) : null;
|
82
|
-
})
|
83
|
-
);
|
84
|
-
return memories.filter(Boolean);
|
85
|
-
}
|
86
|
-
|
87
|
-
async clearMemoryById(id: string): Promise<void> {
|
88
|
-
await this.redis.del(`${this.cachePrefix}${id}`);
|
89
|
-
}
|
90
|
-
|
91
|
-
async clearAllMemories(): Promise<void> {
|
92
|
-
const keys = await this.redis.keys(`${this.cachePrefix}*`);
|
93
|
-
if (keys.length > 0) {
|
94
|
-
await this.redis.del(keys);
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
async quit(): Promise<void> {
|
99
|
-
if (this.redis) {
|
100
|
-
await this.redis.quit();
|
101
|
-
}
|
102
|
-
}
|
103
|
-
}
|
package/memory/index.ts
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
import { BaseMemoryService } from "@/interfaces";
|
2
|
-
import { BaseMemoryType, CreateMemoryInput } from "@/types";
|
3
|
-
|
4
|
-
export abstract class BaseMemory {
|
5
|
-
constructor(protected readonly cacheService: BaseMemoryService) {}
|
6
|
-
|
7
|
-
abstract init(): Promise<void>;
|
8
|
-
abstract createMemory(
|
9
|
-
input: CreateMemoryInput & { embedding?: number[] }
|
10
|
-
): Promise<BaseMemoryType | undefined>;
|
11
|
-
abstract getMemoryById(
|
12
|
-
id: string,
|
13
|
-
roomId: string
|
14
|
-
): Promise<BaseMemoryType | null>;
|
15
|
-
abstract getMemoryByIndex(
|
16
|
-
query: string,
|
17
|
-
options: { roomId: string; limit?: number }
|
18
|
-
): Promise<BaseMemoryType[]>;
|
19
|
-
abstract getAllMemories(roomId: string): Promise<BaseMemoryType[]>;
|
20
|
-
abstract clearMemoryById(id: string, roomId: string): Promise<void>;
|
21
|
-
abstract clearAllMemories(): Promise<void>;
|
22
|
-
}
|
package/services/agenda.ts
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
import { ScheduledRequest } from "@/types";
|
2
|
-
import cron from "node-cron";
|
3
|
-
|
4
|
-
export class Agenda {
|
5
|
-
private scheduledRequests: Map<string, ScheduledRequest> = new Map();
|
6
|
-
private cronJobs: Map<string, cron.ScheduledTask> = new Map();
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Schedule a new request to be processed later
|
10
|
-
*/
|
11
|
-
async scheduleRequest(
|
12
|
-
request: {
|
13
|
-
originalRequest: string;
|
14
|
-
cronExpression: string;
|
15
|
-
},
|
16
|
-
callbacks?: {
|
17
|
-
onScheduled?: (id: string) => void;
|
18
|
-
onExecuted?: (id: string, originalRequest: string) => void;
|
19
|
-
}
|
20
|
-
): Promise<string> {
|
21
|
-
const id = crypto.randomUUID();
|
22
|
-
|
23
|
-
const scheduledRequest: ScheduledRequest = {
|
24
|
-
id,
|
25
|
-
originalRequest: request.originalRequest,
|
26
|
-
cronExpression: request.cronExpression,
|
27
|
-
isRecurring: false,
|
28
|
-
createdAt: new Date(),
|
29
|
-
};
|
30
|
-
|
31
|
-
// Create cron job
|
32
|
-
const cronJob = cron.schedule(request.cronExpression, () => {
|
33
|
-
console.log(`🔄 Executing scheduled request: ${id}`);
|
34
|
-
|
35
|
-
if (callbacks?.onExecuted) {
|
36
|
-
callbacks.onExecuted(id, scheduledRequest.originalRequest);
|
37
|
-
}
|
38
|
-
|
39
|
-
console.log(`✅ Scheduled request executed successfully: ${id}`);
|
40
|
-
|
41
|
-
// Auto-stop pour les tâches non récurrentes
|
42
|
-
if (!scheduledRequest.isRecurring) {
|
43
|
-
this.cancelScheduledRequest(id);
|
44
|
-
}
|
45
|
-
});
|
46
|
-
|
47
|
-
// Démarrer le job en mode non-running
|
48
|
-
cronJob.stop();
|
49
|
-
|
50
|
-
// Store request and job
|
51
|
-
this.scheduledRequests.set(id, scheduledRequest);
|
52
|
-
this.cronJobs.set(id, cronJob);
|
53
|
-
|
54
|
-
if (callbacks?.onScheduled) callbacks.onScheduled(id);
|
55
|
-
|
56
|
-
// Démarrer le job après l'avoir stocké
|
57
|
-
cronJob.start();
|
58
|
-
|
59
|
-
return id;
|
60
|
-
}
|
61
|
-
|
62
|
-
/**
|
63
|
-
* Cancel a scheduled request
|
64
|
-
*/
|
65
|
-
cancelScheduledRequest(requestId: string): boolean {
|
66
|
-
const cronJob = this.cronJobs.get(requestId);
|
67
|
-
if (cronJob) {
|
68
|
-
try {
|
69
|
-
cronJob.stop();
|
70
|
-
this.cronJobs.delete(requestId);
|
71
|
-
this.scheduledRequests.delete(requestId);
|
72
|
-
return true;
|
73
|
-
} catch (error) {
|
74
|
-
console.error(`Failed to stop cron job ${requestId}:`, error);
|
75
|
-
return false;
|
76
|
-
}
|
77
|
-
}
|
78
|
-
return false;
|
79
|
-
}
|
80
|
-
|
81
|
-
/**
|
82
|
-
* Get all scheduled requests
|
83
|
-
*/
|
84
|
-
getScheduledRequests(): ScheduledRequest[] {
|
85
|
-
return Array.from(this.scheduledRequests.values());
|
86
|
-
}
|
87
|
-
|
88
|
-
/**
|
89
|
-
* Stop all cron jobs
|
90
|
-
*/
|
91
|
-
stopAll(): void {
|
92
|
-
const ids = Array.from(this.cronJobs.keys());
|
93
|
-
|
94
|
-
// Arrêter tous les jobs de manière synchrone
|
95
|
-
for (const id of ids) {
|
96
|
-
const job = this.cronJobs.get(id);
|
97
|
-
if (job) {
|
98
|
-
job.stop();
|
99
|
-
this.cronJobs.delete(id);
|
100
|
-
this.scheduledRequests.delete(id);
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
// Double vérification
|
105
|
-
this.cronJobs.clear();
|
106
|
-
this.scheduledRequests.clear();
|
107
|
-
}
|
108
|
-
|
109
|
-
public async stop(): Promise<void> {
|
110
|
-
this.stopAll();
|
111
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
112
|
-
}
|
113
|
-
|
114
|
-
public async cancel(query: {}): Promise<void> {
|
115
|
-
this.stopAll();
|
116
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
117
|
-
}
|
118
|
-
}
|
package/services/embedding.ts
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
import { EmbeddingService } from "@/interfaces";
|
2
|
-
import { cosineSimilarity, embed, EmbeddingModel, embedMany } from "ai";
|
3
|
-
|
4
|
-
export class AIEmbeddingService implements EmbeddingService {
|
5
|
-
constructor(private readonly model: EmbeddingModel<string>) {}
|
6
|
-
|
7
|
-
async embedText(text: string): Promise<number[]> {
|
8
|
-
const { embedding } = await embed({
|
9
|
-
model: this.model,
|
10
|
-
value: text,
|
11
|
-
});
|
12
|
-
return embedding;
|
13
|
-
}
|
14
|
-
|
15
|
-
async embedMany(texts: string[]): Promise<number[][]> {
|
16
|
-
const { embeddings } = await embedMany({
|
17
|
-
model: this.model,
|
18
|
-
values: texts,
|
19
|
-
});
|
20
|
-
return embeddings;
|
21
|
-
}
|
22
|
-
|
23
|
-
calculateSimilarity(embedding1: number[], embedding2: number[]): number {
|
24
|
-
return (cosineSimilarity(embedding1, embedding2) + 1) * 50;
|
25
|
-
}
|
26
|
-
}
|