@ai.ntellect/core 0.3.1 โ 0.4.0
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/.nvmrc +1 -0
- package/README.FR.md +201 -261
- package/README.md +208 -260
- package/agent/index.ts +204 -185
- package/agent/tools/get-rss.ts +64 -0
- package/bull.ts +5 -0
- package/dist/agent/index.d.ts +29 -22
- package/dist/agent/index.js +124 -97
- package/dist/agent/tools/get-rss.d.ts +16 -0
- package/dist/agent/tools/get-rss.js +62 -0
- package/dist/bull.d.ts +1 -0
- package/dist/bull.js +9 -0
- package/dist/examples/index.d.ts +2 -0
- package/dist/examples/index.js +89 -0
- package/dist/llm/interpreter/context.d.ts +5 -22
- package/dist/llm/interpreter/context.js +8 -9
- package/dist/llm/interpreter/index.d.ts +9 -5
- package/dist/llm/interpreter/index.js +55 -48
- package/dist/llm/memory-manager/context.d.ts +2 -0
- package/dist/llm/memory-manager/context.js +22 -0
- package/dist/llm/memory-manager/index.d.ts +17 -0
- package/dist/llm/memory-manager/index.js +107 -0
- package/dist/llm/orchestrator/context.d.ts +2 -10
- package/dist/llm/orchestrator/context.js +19 -16
- package/dist/llm/orchestrator/index.d.ts +36 -21
- package/dist/llm/orchestrator/index.js +122 -88
- package/dist/llm/orchestrator/types.d.ts +12 -0
- package/dist/llm/orchestrator/types.js +2 -0
- package/dist/memory/cache.d.ts +6 -6
- package/dist/memory/cache.js +35 -42
- package/dist/memory/persistent.d.ts +9 -13
- package/dist/memory/persistent.js +94 -114
- package/dist/services/redis-cache.d.ts +37 -0
- package/dist/services/redis-cache.js +93 -0
- package/dist/services/scheduler.d.ts +40 -0
- package/dist/services/scheduler.js +99 -0
- package/dist/services/telegram-monitor.d.ts +0 -0
- package/dist/services/telegram-monitor.js +118 -0
- package/dist/test.d.ts +0 -167
- package/dist/test.js +437 -372
- package/dist/types.d.ts +60 -9
- package/dist/utils/generate-object.d.ts +12 -0
- package/dist/utils/generate-object.js +90 -0
- package/dist/utils/header-builder.d.ts +11 -0
- package/dist/utils/header-builder.js +34 -0
- package/dist/utils/inject-actions.js +2 -2
- package/dist/utils/queue-item-transformer.d.ts +2 -2
- package/dist/utils/schema-generator.d.ts +16 -0
- package/dist/utils/schema-generator.js +46 -0
- package/examples/index.ts +103 -0
- package/llm/interpreter/context.ts +20 -8
- package/llm/interpreter/index.ts +81 -54
- package/llm/memory-manager/context.ts +21 -0
- package/llm/memory-manager/index.ts +163 -0
- package/llm/orchestrator/context.ts +20 -13
- package/llm/orchestrator/index.ts +210 -130
- package/llm/orchestrator/types.ts +14 -0
- package/memory/cache.ts +41 -55
- package/memory/persistent.ts +121 -149
- package/package.json +11 -2
- package/services/redis-cache.ts +128 -0
- package/services/scheduler.ts +128 -0
- package/services/telegram-monitor.ts +138 -0
- package/t.py +79 -0
- package/t.spec +38 -0
- package/types.ts +64 -9
- package/utils/generate-object.ts +105 -0
- package/utils/header-builder.ts +40 -0
- package/utils/inject-actions.ts +4 -6
- package/utils/queue-item-transformer.ts +2 -1
- package/utils/schema-generator.ts +73 -0
- package/agent/handlers/ActionHandler.ts +0 -48
- package/agent/handlers/ConfirmationHandler.ts +0 -37
- package/agent/handlers/EventHandler.ts +0 -35
- package/dist/agent/handlers/ActionHandler.d.ts +0 -8
- package/dist/agent/handlers/ActionHandler.js +0 -36
- package/dist/agent/handlers/ConfirmationHandler.d.ts +0 -7
- package/dist/agent/handlers/ConfirmationHandler.js +0 -31
- package/dist/agent/handlers/EventHandler.d.ts +0 -10
- package/dist/agent/handlers/EventHandler.js +0 -34
- package/dist/llm/evaluator/context.d.ts +0 -10
- package/dist/llm/evaluator/context.js +0 -22
- package/dist/llm/evaluator/index.d.ts +0 -16
- package/dist/llm/evaluator/index.js +0 -151
- package/llm/evaluator/context.ts +0 -21
- package/llm/evaluator/index.ts +0 -194
package/dist/memory/cache.d.ts
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
import { CacheMemoryOptions, CacheMemoryType, CreateMemoryInput, MatchOptions, MemoryScope
|
1
|
+
import { CacheMemoryOptions, CacheMemoryType, CreateMemoryInput, MatchOptions, MemoryScope } from "../types";
|
2
2
|
export declare class CacheMemory {
|
3
3
|
private redis;
|
4
4
|
private readonly CACHE_PREFIX;
|
5
5
|
private readonly CACHE_TTL;
|
6
|
-
|
6
|
+
private readonly embeddingModel;
|
7
|
+
constructor(options: CacheMemoryOptions);
|
7
8
|
private initRedis;
|
8
|
-
private getMemoryKey;
|
9
9
|
private storeMemory;
|
10
10
|
findSimilarActions(query: string, options?: MatchOptions & {
|
11
11
|
userId?: string;
|
12
12
|
scope?: MemoryScope;
|
13
13
|
}): Promise<{
|
14
|
-
|
15
|
-
similarityPercentage: number;
|
14
|
+
data: any;
|
16
15
|
query: string;
|
16
|
+
createdAt: Date;
|
17
17
|
}[]>;
|
18
|
-
getAllMemories(
|
18
|
+
getAllMemories(): Promise<CacheMemoryType[]>;
|
19
19
|
private getMemoriesFromKeys;
|
20
20
|
createMemory(input: CreateMemoryInput): Promise<CacheMemoryType | undefined>;
|
21
21
|
private createSingleMemory;
|
package/dist/memory/cache.js
CHANGED
@@ -6,7 +6,8 @@ const ai_1 = require("ai");
|
|
6
6
|
const redis_1 = require("redis");
|
7
7
|
const types_1 = require("../types");
|
8
8
|
class CacheMemory {
|
9
|
-
constructor(options
|
9
|
+
constructor(options) {
|
10
|
+
this.embeddingModel = options.embeddingModel;
|
10
11
|
const ttlInHours = options.cacheTTL ?? 1;
|
11
12
|
this.CACHE_TTL = ttlInHours * 60 * 60;
|
12
13
|
this.CACHE_PREFIX = options.cachePrefix ?? "memory:";
|
@@ -31,17 +32,11 @@ class CacheMemory {
|
|
31
32
|
console.error("โ Failed to connect to Redis:", error);
|
32
33
|
}
|
33
34
|
}
|
34
|
-
|
35
|
-
|
36
|
-
return `${this.CACHE_PREFIX}global:`;
|
37
|
-
}
|
38
|
-
return `${this.CACHE_PREFIX}user:${userId}:`;
|
39
|
-
}
|
40
|
-
async storeMemory(memory) {
|
41
|
-
const prefix = this.getMemoryKey(memory.scope, memory.userId);
|
35
|
+
async storeMemory(memory, ttl) {
|
36
|
+
const prefix = this.CACHE_PREFIX;
|
42
37
|
const key = `${prefix}${memory.id}`;
|
43
38
|
const result = await this.redis.set(key, JSON.stringify(memory), {
|
44
|
-
EX: this.CACHE_TTL,
|
39
|
+
EX: ttl || this.CACHE_TTL,
|
45
40
|
});
|
46
41
|
console.log("๐พ Cache memory created:", result);
|
47
42
|
}
|
@@ -53,14 +48,14 @@ class CacheMemory {
|
|
53
48
|
model: openai_1.openai.embedding("text-embedding-3-small"),
|
54
49
|
value: query,
|
55
50
|
});
|
56
|
-
const memories = await this.getAllMemories(
|
51
|
+
const memories = await this.getAllMemories();
|
57
52
|
console.log(`\n๐ Found ${memories.length} cached queries to compare`);
|
58
53
|
const matches = memories
|
59
54
|
.map((memory) => {
|
60
55
|
const similarity = (0, ai_1.cosineSimilarity)(embedding, memory.embedding);
|
61
56
|
const similarityPercentage = (similarity + 1) * 50;
|
62
57
|
return {
|
63
|
-
|
58
|
+
data: memory.data,
|
64
59
|
query: memory.query,
|
65
60
|
similarityPercentage,
|
66
61
|
createdAt: memory.createdAt,
|
@@ -77,6 +72,7 @@ class CacheMemory {
|
|
77
72
|
results.forEach((match, index) => {
|
78
73
|
console.log(`\n${index + 1}. Match Details:`);
|
79
74
|
console.log(` Query: ${match.query}`);
|
75
|
+
console.log(` Data: ${JSON.stringify(match.data)}`);
|
80
76
|
console.log(` Similarity: ${match.similarityPercentage.toFixed(2)}%`);
|
81
77
|
console.log("โ".repeat(50));
|
82
78
|
});
|
@@ -84,23 +80,18 @@ class CacheMemory {
|
|
84
80
|
else {
|
85
81
|
console.log("\nโ No similar queries found in cache");
|
86
82
|
}
|
87
|
-
return results
|
83
|
+
return results.map((match) => {
|
84
|
+
return {
|
85
|
+
data: match.data,
|
86
|
+
query: match.query,
|
87
|
+
createdAt: match.createdAt,
|
88
|
+
};
|
89
|
+
});
|
88
90
|
}
|
89
|
-
async getAllMemories(
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
const globalKeys = await this.redis.keys(`${globalPrefix}*`);
|
94
|
-
const globalPatterns = await this.getMemoriesFromKeys(globalKeys);
|
95
|
-
patterns = patterns.concat(globalPatterns);
|
96
|
-
}
|
97
|
-
if (userId && (!scope || scope === types_1.MemoryScope.USER)) {
|
98
|
-
const userPrefix = this.getMemoryKey(types_1.MemoryScope.USER, userId);
|
99
|
-
const userKeys = await this.redis.keys(`${userPrefix}*`);
|
100
|
-
const userPatterns = await this.getMemoriesFromKeys(userKeys);
|
101
|
-
patterns = patterns.concat(userPatterns);
|
102
|
-
}
|
103
|
-
return patterns;
|
91
|
+
async getAllMemories() {
|
92
|
+
const keys = await this.redis.keys(`${this.CACHE_PREFIX}*`);
|
93
|
+
const memories = await this.getMemoriesFromKeys(keys);
|
94
|
+
return memories;
|
104
95
|
}
|
105
96
|
async getMemoriesFromKeys(keys) {
|
106
97
|
const memories = [];
|
@@ -114,10 +105,9 @@ class CacheMemory {
|
|
114
105
|
}
|
115
106
|
async createMemory(input) {
|
116
107
|
console.log("\n๐ Processing new memory creation");
|
117
|
-
console.log("Content:", input.
|
118
|
-
console.log("
|
119
|
-
|
120
|
-
const existingPattern = await this.findSimilarActions(input.content, {
|
108
|
+
console.log("Content:", input.query);
|
109
|
+
console.log("TTL:", input.ttl ? `${input.ttl} seconds` : "default");
|
110
|
+
const existingPattern = await this.findSimilarActions(input.query, {
|
121
111
|
similarityThreshold: 95,
|
122
112
|
userId: input.userId,
|
123
113
|
scope: input.scope,
|
@@ -128,7 +118,8 @@ class CacheMemory {
|
|
128
118
|
existingPattern.forEach((match, index) => {
|
129
119
|
console.log(`\n${index + 1}. Existing Match:`);
|
130
120
|
console.log(` Query: ${match.query}`);
|
131
|
-
console.log(`
|
121
|
+
console.log(` Data: ${JSON.stringify(match.data)}`);
|
122
|
+
console.log(` Created At: ${match.createdAt}`);
|
132
123
|
});
|
133
124
|
console.log("\nโญ๏ธ Skipping creation of new memory");
|
134
125
|
return;
|
@@ -136,36 +127,38 @@ class CacheMemory {
|
|
136
127
|
console.log("\n๐ No similar memory found - creating new one");
|
137
128
|
const memory = await this.createSingleMemory({
|
138
129
|
id: crypto.randomUUID(),
|
139
|
-
|
140
|
-
type: input.type,
|
130
|
+
query: input.query,
|
141
131
|
data: input.data,
|
142
132
|
userId: input.userId,
|
143
133
|
scope: input.scope,
|
134
|
+
ttl: input.ttl,
|
144
135
|
});
|
145
136
|
return memory;
|
146
137
|
}
|
147
138
|
async createSingleMemory(params) {
|
148
139
|
console.log("\n๐๏ธ Creating new cache memory");
|
149
140
|
console.log("ID:", params.id);
|
150
|
-
console.log("Content:", params.
|
141
|
+
console.log("Content:", params.query);
|
151
142
|
console.log("\n๐งฎ Generating embedding...");
|
152
143
|
const { embedding } = await (0, ai_1.embed)({
|
153
|
-
model:
|
154
|
-
value: params.
|
144
|
+
model: this.embeddingModel,
|
145
|
+
value: params.query,
|
155
146
|
});
|
156
147
|
console.log("โ
Embedding generated successfully");
|
157
148
|
const memory = {
|
158
149
|
id: params.id,
|
159
|
-
type: params.type,
|
160
150
|
data: params.data,
|
161
|
-
query: params.
|
151
|
+
query: params.query,
|
162
152
|
embedding,
|
163
153
|
userId: params.userId,
|
164
154
|
scope: params.scope || (params.userId ? types_1.MemoryScope.USER : types_1.MemoryScope.GLOBAL),
|
165
155
|
createdAt: new Date(),
|
166
156
|
};
|
167
|
-
await this.storeMemory(memory);
|
168
|
-
console.log("โ
|
157
|
+
await this.storeMemory(memory, params.ttl);
|
158
|
+
console.log("โ
Short-term memory created and stored successfully", {
|
159
|
+
...memory,
|
160
|
+
ttl: params.ttl || this.CACHE_TTL,
|
161
|
+
});
|
169
162
|
return memory;
|
170
163
|
}
|
171
164
|
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import {
|
1
|
+
import { EmbeddingModel } from "ai";
|
2
|
+
import { LongTermMemory, MemoryScope } from "../types";
|
2
3
|
interface SearchOptions {
|
3
4
|
scope?: MemoryScope;
|
4
5
|
userId?: string;
|
@@ -16,10 +17,12 @@ export declare class PersistentMemory {
|
|
16
17
|
private readonly host;
|
17
18
|
private readonly apiKey;
|
18
19
|
private readonly INDEX_PREFIX;
|
20
|
+
private readonly embeddingModel;
|
19
21
|
constructor(options: {
|
20
22
|
host: string;
|
21
23
|
apiKey: string;
|
22
24
|
indexPrefix?: string;
|
25
|
+
embeddingModel: EmbeddingModel<string>;
|
23
26
|
});
|
24
27
|
/**
|
25
28
|
* Initialize indexes
|
@@ -29,10 +32,6 @@ export declare class PersistentMemory {
|
|
29
32
|
* Make API request to Meilisearch
|
30
33
|
*/
|
31
34
|
private _makeRequest;
|
32
|
-
/**
|
33
|
-
* Get index name based on scope and userId
|
34
|
-
*/
|
35
|
-
private _getIndexName;
|
36
35
|
/**
|
37
36
|
* Get or create an index with proper settings
|
38
37
|
*/
|
@@ -41,21 +40,18 @@ export declare class PersistentMemory {
|
|
41
40
|
/**
|
42
41
|
* Store a memory in the database
|
43
42
|
*/
|
44
|
-
createMemory(memory:
|
43
|
+
createMemory(memory: LongTermMemory): Promise<unknown>;
|
45
44
|
/**
|
46
45
|
* Find best matching memories
|
47
46
|
*/
|
48
|
-
|
49
|
-
createdAt: string;
|
50
|
-
data: any;
|
51
|
-
purpose: string;
|
47
|
+
findRelevantDocuments(query: string, options?: SearchOptions): Promise<{
|
52
48
|
query: string;
|
53
|
-
|
54
|
-
|
49
|
+
data: any;
|
50
|
+
createdAt: string;
|
55
51
|
}[]>;
|
56
52
|
/**
|
57
53
|
* Delete memories for a given scope and user
|
58
54
|
*/
|
59
|
-
deleteMemories(
|
55
|
+
deleteMemories(): Promise<unknown>;
|
60
56
|
}
|
61
57
|
export {};
|
@@ -1,10 +1,8 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.PersistentMemory = void 0;
|
4
|
-
const openai_1 = require("@ai-sdk/openai");
|
5
4
|
const ai_1 = require("ai");
|
6
5
|
const text_splitter_1 = require("langchain/text_splitter");
|
7
|
-
const types_1 = require("../types");
|
8
6
|
/**
|
9
7
|
* Handles persistent memory storage using Meilisearch API
|
10
8
|
*/
|
@@ -12,22 +10,29 @@ class PersistentMemory {
|
|
12
10
|
constructor(options) {
|
13
11
|
this.host = options.host;
|
14
12
|
this.apiKey = options.apiKey;
|
15
|
-
this.INDEX_PREFIX = options.indexPrefix || "
|
13
|
+
this.INDEX_PREFIX = options.indexPrefix || "memory";
|
14
|
+
this.embeddingModel = options.embeddingModel;
|
16
15
|
}
|
17
16
|
/**
|
18
17
|
* Initialize indexes
|
19
18
|
*/
|
20
19
|
async init() {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
try {
|
21
|
+
// Create or get main index
|
22
|
+
await this._getOrCreateIndex(this.INDEX_PREFIX);
|
23
|
+
console.log(`โ
Index '${this.INDEX_PREFIX}' initialized successfully`);
|
24
|
+
}
|
25
|
+
catch (error) {
|
26
|
+
console.error(`โ Failed to initialize index: ${error}`);
|
27
|
+
throw error;
|
28
|
+
}
|
25
29
|
}
|
26
30
|
/**
|
27
31
|
* Make API request to Meilisearch
|
28
32
|
*/
|
29
33
|
async _makeRequest(path, options = {}) {
|
30
34
|
const url = `${this.host}${path}`;
|
35
|
+
console.log("๐ Making request to Meilisearch:", url);
|
31
36
|
const response = await fetch(url, {
|
32
37
|
...options,
|
33
38
|
headers: {
|
@@ -42,28 +47,25 @@ class PersistentMemory {
|
|
42
47
|
}
|
43
48
|
return response.json();
|
44
49
|
}
|
45
|
-
/**
|
46
|
-
* Get index name based on scope and userId
|
47
|
-
*/
|
48
|
-
_getIndexName(scope, userId) {
|
49
|
-
if (scope === "global") {
|
50
|
-
return `${this.INDEX_PREFIX}global`;
|
51
|
-
}
|
52
|
-
return `${this.INDEX_PREFIX}user_${userId}`;
|
53
|
-
}
|
54
50
|
/**
|
55
51
|
* Get or create an index with proper settings
|
56
52
|
*/
|
57
53
|
async _getOrCreateIndex(indexName) {
|
58
54
|
try {
|
59
|
-
//
|
60
|
-
await this._makeRequest(
|
61
|
-
method: "
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
55
|
+
// Check if index exists first
|
56
|
+
const indexExists = await this._makeRequest(`/indexes/${indexName}`, {
|
57
|
+
method: "GET",
|
58
|
+
}).catch(() => false);
|
59
|
+
if (!indexExists) {
|
60
|
+
console.log(`Creating new index: ${indexName}`);
|
61
|
+
await this._makeRequest("/indexes", {
|
62
|
+
method: "POST",
|
63
|
+
body: JSON.stringify({
|
64
|
+
uid: indexName,
|
65
|
+
primaryKey: "id",
|
66
|
+
}),
|
67
|
+
});
|
68
|
+
}
|
67
69
|
// Update index settings
|
68
70
|
const settings = {
|
69
71
|
searchableAttributes: ["query", "purpose", "chunks.content"],
|
@@ -73,12 +75,11 @@ class PersistentMemory {
|
|
73
75
|
method: "PATCH",
|
74
76
|
body: JSON.stringify(settings),
|
75
77
|
});
|
78
|
+
console.log(`Index ${indexName} configured successfully`);
|
76
79
|
}
|
77
80
|
catch (error) {
|
78
|
-
|
79
|
-
|
80
|
-
throw error;
|
81
|
-
}
|
81
|
+
console.error(`Failed to configure index ${indexName}:`, error);
|
82
|
+
throw error;
|
82
83
|
}
|
83
84
|
}
|
84
85
|
async processContent(content) {
|
@@ -89,7 +90,7 @@ class PersistentMemory {
|
|
89
90
|
const chunks = await textSplitter.createDocuments([content]);
|
90
91
|
// Generate embeddings for all chunks
|
91
92
|
const { embeddings } = await (0, ai_1.embedMany)({
|
92
|
-
model:
|
93
|
+
model: this.embeddingModel,
|
93
94
|
values: chunks.map((chunk) => chunk.pageContent),
|
94
95
|
});
|
95
96
|
// Create processed chunks with embeddings
|
@@ -102,106 +103,85 @@ class PersistentMemory {
|
|
102
103
|
* Store a memory in the database
|
103
104
|
*/
|
104
105
|
async createMemory(memory) {
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
106
|
+
try {
|
107
|
+
console.log(`๐ Creating memory in index: ${this.INDEX_PREFIX}`);
|
108
|
+
// Process content into chunks with embeddings
|
109
|
+
const chunks = await this.processContent(memory.data);
|
110
|
+
// Generate unique ID if not provided
|
111
|
+
const id = memory.id || crypto.randomUUID();
|
112
|
+
const document = {
|
113
|
+
...memory,
|
114
|
+
chunks,
|
115
|
+
createdAt: memory.createdAt.toISOString(),
|
116
|
+
};
|
117
|
+
const response = await this._makeRequest(`/indexes/${this.INDEX_PREFIX}/documents`, {
|
118
|
+
method: "POST",
|
119
|
+
body: JSON.stringify([document]),
|
120
|
+
});
|
121
|
+
console.log("โ
Memory created successfully", { id });
|
122
|
+
return response;
|
123
|
+
}
|
124
|
+
catch (error) {
|
125
|
+
console.error("โ Failed to create memory:", error);
|
126
|
+
throw error;
|
127
|
+
}
|
119
128
|
}
|
120
129
|
/**
|
121
130
|
* Find best matching memories
|
122
131
|
*/
|
123
|
-
async
|
124
|
-
console.log(
|
132
|
+
async findRelevantDocuments(query, options = {}) {
|
133
|
+
console.log(`\n๐ Searching in index: ${this.INDEX_PREFIX}`);
|
125
134
|
console.log("Query:", query);
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
if (!options.scope || options.scope === "global") {
|
135
|
-
const globalIndex = this._getIndexName(types_1.MemoryScope.GLOBAL);
|
136
|
-
console.log("\n๐ Searching in global index:", globalIndex);
|
137
|
-
try {
|
138
|
-
const globalResults = await this._makeRequest(`/indexes/${globalIndex}/search`, {
|
139
|
-
method: "POST",
|
140
|
-
body: JSON.stringify({ q: query }),
|
141
|
-
});
|
142
|
-
if (globalResults?.hits) {
|
143
|
-
searchResults.push(...globalResults.hits);
|
144
|
-
}
|
145
|
-
}
|
146
|
-
catch (error) {
|
147
|
-
console.error("โ Error searching global index:", error);
|
148
|
-
}
|
149
|
-
}
|
150
|
-
// Search in user memories
|
151
|
-
if (options.userId &&
|
152
|
-
(!options.scope || options.scope === types_1.MemoryScope.USER)) {
|
153
|
-
const userIndex = this._getIndexName(types_1.MemoryScope.USER, options.userId);
|
154
|
-
const userResults = await this._makeRequest(`/indexes/${userIndex}/search`, {
|
135
|
+
try {
|
136
|
+
// Generate embedding for the query
|
137
|
+
const { embedding: queryEmbedding } = await (0, ai_1.embed)({
|
138
|
+
model: this.embeddingModel,
|
139
|
+
value: query,
|
140
|
+
});
|
141
|
+
// Search in the index
|
142
|
+
const searchResults = await this._makeRequest(`/indexes/${this.INDEX_PREFIX}/search`, {
|
155
143
|
method: "POST",
|
156
|
-
body: JSON.stringify({
|
144
|
+
body: JSON.stringify({
|
145
|
+
q: query,
|
146
|
+
limit: options.maxResults || 10,
|
147
|
+
}),
|
157
148
|
});
|
158
|
-
if (
|
159
|
-
|
149
|
+
if (!searchResults?.hits?.length) {
|
150
|
+
console.log("โ No matches found");
|
151
|
+
return [];
|
160
152
|
}
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
153
|
+
// Process and filter results using cosine similarity
|
154
|
+
const results = searchResults.hits
|
155
|
+
.flatMap((hit) => {
|
156
|
+
const chunkSimilarities = hit.chunks.map((chunk) => ({
|
157
|
+
query: hit.query,
|
158
|
+
data: hit.data,
|
159
|
+
similarityPercentage: ((0, ai_1.cosineSimilarity)(queryEmbedding, chunk.embedding) + 1) * 50,
|
160
|
+
createdAt: hit.createdAt,
|
161
|
+
}));
|
162
|
+
return chunkSimilarities.reduce((best, current) => current.similarityPercentage > best.similarityPercentage
|
163
|
+
? current
|
164
|
+
: best, chunkSimilarities[0]);
|
165
|
+
})
|
166
|
+
.filter((match) => match.similarityPercentage >= (options.similarityThreshold || 70))
|
167
|
+
.sort((a, b) => b.similarityPercentage - a.similarityPercentage);
|
168
|
+
console.log(`โจ Found ${results.length} relevant matches`);
|
169
|
+
return results.map((result) => ({
|
170
|
+
query: result.query,
|
171
|
+
data: result.data,
|
172
|
+
createdAt: result.createdAt,
|
174
173
|
}));
|
175
|
-
return chunkSimilarities.reduce((best, current) => current.similarityPercentage > best.similarityPercentage
|
176
|
-
? current
|
177
|
-
: best, chunkSimilarities[0]);
|
178
|
-
})
|
179
|
-
.filter((match) => match.similarityPercentage >= (options.similarityThreshold || 70))
|
180
|
-
.sort((a, b) => b.similarityPercentage - a.similarityPercentage);
|
181
|
-
// Log filtered results in a more structured way
|
182
|
-
if (results.length > 0) {
|
183
|
-
console.log("\nโจ Relevant matches found:");
|
184
|
-
console.log("โ".repeat(50));
|
185
|
-
results.forEach((match, index) => {
|
186
|
-
console.log(`\n${index + 1}. Match Details:`);
|
187
|
-
console.log(` Query: ${match.query}`);
|
188
|
-
console.log(` Purpose: ${match.purpose}`);
|
189
|
-
console.log(` Similarity: ${match.similarityPercentage.toFixed(2)}%`);
|
190
|
-
console.log(` Content: "${match.chunk}"`);
|
191
|
-
console.log("โ".repeat(50));
|
192
|
-
});
|
193
174
|
}
|
194
|
-
|
195
|
-
console.
|
175
|
+
catch (error) {
|
176
|
+
console.error("โ Search failed:", error);
|
177
|
+
return [];
|
196
178
|
}
|
197
|
-
return results;
|
198
179
|
}
|
199
180
|
/**
|
200
181
|
* Delete memories for a given scope and user
|
201
182
|
*/
|
202
|
-
async deleteMemories(
|
203
|
-
|
204
|
-
return this._makeRequest(`/indexes/${indexName}`, {
|
183
|
+
async deleteMemories() {
|
184
|
+
return this._makeRequest(`/indexes/${this.INDEX_PREFIX}`, {
|
205
185
|
method: "DELETE",
|
206
186
|
});
|
207
187
|
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
export interface CacheConfig {
|
2
|
+
host: string;
|
3
|
+
port: number;
|
4
|
+
password?: string;
|
5
|
+
ttl?: number;
|
6
|
+
cleanupInterval?: string;
|
7
|
+
}
|
8
|
+
export declare class RedisCache {
|
9
|
+
private redis;
|
10
|
+
private readonly defaultTTL;
|
11
|
+
private readonly cleanupJob;
|
12
|
+
constructor(config: CacheConfig);
|
13
|
+
/**
|
14
|
+
* Store previous actions for a specific request
|
15
|
+
*/
|
16
|
+
storePreviousActions(requestId: string, actions: any[]): Promise<void>;
|
17
|
+
/**
|
18
|
+
* Get previous actions for a specific request
|
19
|
+
*/
|
20
|
+
getPreviousActions(requestId: string): Promise<any[]>;
|
21
|
+
/**
|
22
|
+
* Store a recent message
|
23
|
+
*/
|
24
|
+
storeRecentMessage(message: string, metadata?: Record<string, any>): Promise<void>;
|
25
|
+
/**
|
26
|
+
* Get recent messages
|
27
|
+
*/
|
28
|
+
getRecentMessages(limit?: number): Promise<any[]>;
|
29
|
+
/**
|
30
|
+
* Cleanup expired keys
|
31
|
+
*/
|
32
|
+
private cleanup;
|
33
|
+
/**
|
34
|
+
* Stop the cleanup job and close Redis connection
|
35
|
+
*/
|
36
|
+
close(): Promise<void>;
|
37
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.RedisCache = void 0;
|
7
|
+
const ioredis_1 = __importDefault(require("ioredis"));
|
8
|
+
const node_cron_1 = __importDefault(require("node-cron"));
|
9
|
+
class RedisCache {
|
10
|
+
constructor(config) {
|
11
|
+
this.redis = new ioredis_1.default({
|
12
|
+
host: config.host,
|
13
|
+
port: config.port,
|
14
|
+
password: config.password,
|
15
|
+
});
|
16
|
+
this.defaultTTL = config.ttl || 1800; // 30 minutes in seconds
|
17
|
+
// Setup cleanup job (default: every 30 minutes)
|
18
|
+
this.cleanupJob = node_cron_1.default.schedule(config.cleanupInterval || "*/30 * * * *", () => this.cleanup());
|
19
|
+
}
|
20
|
+
/**
|
21
|
+
* Store previous actions for a specific request
|
22
|
+
*/
|
23
|
+
async storePreviousActions(requestId, actions) {
|
24
|
+
const key = `previous_actions:${requestId}`;
|
25
|
+
await this.redis.setex(key, this.defaultTTL, JSON.stringify({
|
26
|
+
timestamp: new Date().toISOString(),
|
27
|
+
actions,
|
28
|
+
}));
|
29
|
+
}
|
30
|
+
/**
|
31
|
+
* Get previous actions for a specific request
|
32
|
+
*/
|
33
|
+
async getPreviousActions(requestId) {
|
34
|
+
const key = `previous_actions:${requestId}`;
|
35
|
+
const data = await this.redis.get(key);
|
36
|
+
if (!data)
|
37
|
+
return [];
|
38
|
+
const parsed = JSON.parse(data);
|
39
|
+
return parsed.actions;
|
40
|
+
}
|
41
|
+
/**
|
42
|
+
* Store a recent message
|
43
|
+
*/
|
44
|
+
async storeRecentMessage(message, metadata) {
|
45
|
+
const id = crypto.randomUUID();
|
46
|
+
const key = `recent_messages:${id}`;
|
47
|
+
await this.redis.setex(key, this.defaultTTL, JSON.stringify({
|
48
|
+
timestamp: new Date().toISOString(),
|
49
|
+
message,
|
50
|
+
metadata,
|
51
|
+
}));
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Get recent messages
|
55
|
+
*/
|
56
|
+
async getRecentMessages(limit = 10) {
|
57
|
+
const keys = await this.redis.keys("recent_messages:*");
|
58
|
+
if (!keys.length)
|
59
|
+
return [];
|
60
|
+
const messages = await Promise.all(keys.map(async (key) => {
|
61
|
+
const data = await this.redis.get(key);
|
62
|
+
return data ? JSON.parse(data) : null;
|
63
|
+
}));
|
64
|
+
return messages
|
65
|
+
.filter(Boolean)
|
66
|
+
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
67
|
+
.slice(0, limit);
|
68
|
+
}
|
69
|
+
/**
|
70
|
+
* Cleanup expired keys
|
71
|
+
*/
|
72
|
+
async cleanup() {
|
73
|
+
console.log("๐งน Starting cache cleanup...");
|
74
|
+
try {
|
75
|
+
// Redis automatically removes expired keys
|
76
|
+
// This is just for logging purposes
|
77
|
+
const actionKeys = await this.redis.keys("previous_actions:*");
|
78
|
+
const messageKeys = await this.redis.keys("recent_messages:*");
|
79
|
+
console.log(`Cache status: ${actionKeys.length} actions, ${messageKeys.length} messages`);
|
80
|
+
}
|
81
|
+
catch (error) {
|
82
|
+
console.error("โ Cache cleanup error:", error);
|
83
|
+
}
|
84
|
+
}
|
85
|
+
/**
|
86
|
+
* Stop the cleanup job and close Redis connection
|
87
|
+
*/
|
88
|
+
async close() {
|
89
|
+
this.cleanupJob.stop();
|
90
|
+
await this.redis.quit();
|
91
|
+
}
|
92
|
+
}
|
93
|
+
exports.RedisCache = RedisCache;
|