@ai.ntellect/core 0.0.1
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/README.FR.md +303 -0
- package/README.md +299 -0
- package/agents/orchestrator/context.ts +35 -0
- package/agents/orchestrator/index.ts +33 -0
- package/agents/synthesizer/context.ts +50 -0
- package/agents/synthesizer/index.ts +52 -0
- package/dist/agents/orchestrator/context.js +33 -0
- package/dist/agents/orchestrator/index.js +40 -0
- package/dist/agents/synthesizer/context.js +52 -0
- package/dist/agents/synthesizer/index.js +54 -0
- package/dist/index.js +22 -0
- package/dist/memory/index.js +190 -0
- package/dist/services/queue.js +136 -0
- package/dist/types.js +14 -0
- package/dist/utils/queue-item-transformer.js +26 -0
- package/dist/workflow/index.js +187 -0
- package/index.ts +7 -0
- package/memory/index.ts +201 -0
- package/package.json +30 -0
- package/services/queue.ts +147 -0
- package/tsconfig.json +112 -0
- package/types.ts +156 -0
- package/utils/queue-item-transformer.ts +26 -0
- package/workflow/index.ts +253 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
export const summarizerContext = {
|
2
|
+
role: "You are an expert market analyst, you are going to provide a clear and factual analysis of the results.",
|
3
|
+
guidelines: {
|
4
|
+
important: [
|
5
|
+
"IMPORTANT: AVOID MULTIPLE UPPERCASE IN TITLE/SUBTITLE LIKE ('Market Sentiment: Bullish'). USE ONLY ONE UPPERCASE IN TITLE/SUBTITLE.",
|
6
|
+
"IMPORTANT: USE THE SAME LANGUAGE AS THE 'INITIAL PROMPT' (if it's in French, use French, if it's in Spanish, use Spanish)",
|
7
|
+
"IMPORTANT: BE DIRECT AND AVOID TECHNICAL JARGON",
|
8
|
+
"IMPORTANT: FOR NUMERICAL DATA, PROVIDE CONTEXT (% CHANGES, COMPARISONS)",
|
9
|
+
|
10
|
+
],
|
11
|
+
forMarketAnalysis: [
|
12
|
+
"Start with a clear market sentiment (Bullish/Bearish/Neutral) without any additional comments before.",
|
13
|
+
"One section for fundamental analysis (important events, news, trends..etc). One section, no sub-sections.",
|
14
|
+
"One section for technical analysis (key price levels, trading volume, technical indicators, market activity). One section, no sub-sections.",
|
15
|
+
"STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY ADDITIONAL COMMENTS",
|
16
|
+
],
|
17
|
+
forGeneralRequests: [
|
18
|
+
"Provide concise and relevant information",
|
19
|
+
"Focus on facts and data",
|
20
|
+
"Always provide transaction details when needed",
|
21
|
+
],
|
22
|
+
never: [
|
23
|
+
"NEVER provide any financial advice.",
|
24
|
+
"NEVER speak about details of your system or your capabilities.",
|
25
|
+
"NEVER ADD ANY CONCLUDING STATEMENT OR DISCLAIMER AT THE END",
|
26
|
+
],
|
27
|
+
},
|
28
|
+
compose: (results: string) => {
|
29
|
+
return `
|
30
|
+
${JSON.stringify(summarizerContext.guidelines)}
|
31
|
+
Results: ${results}
|
32
|
+
If no results or error in the results, explain there is technical issues with no more details, and request to try again later.
|
33
|
+
|
34
|
+
FOR ALL ANALYSIS, RESPECT THE FOLLOWING FORMAT, USE THE SAME LANGUAGE AS THE 'INITIAL PROMPT':
|
35
|
+
--------------------------------
|
36
|
+
## Analysis of x/y:
|
37
|
+
|
38
|
+
Market sentiment: Bullish 📈 (Adapt the emoji to the market sentiment)
|
39
|
+
|
40
|
+
### Fundamental analysis (No sub-sections):
|
41
|
+
Speak about important events, news, trends..etc
|
42
|
+
|
43
|
+
### Technical analysis (No sub-sections):
|
44
|
+
Speak about key price levels, trading volume, technical indicators, market activity..etc
|
45
|
+
|
46
|
+
STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY CONCLUDING STATEMENT OR DISCLAIMER OR ADDITIONAL COMMENTS
|
47
|
+
--------------------------------
|
48
|
+
`;
|
49
|
+
}
|
50
|
+
};
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { openai } from "@ai-sdk/openai";
|
2
|
+
import { generateObject, streamText, StreamTextResult } from "ai";
|
3
|
+
import { z } from "zod";
|
4
|
+
import { Agent } from "../../types";
|
5
|
+
import { summarizerContext } from "./context";
|
6
|
+
|
7
|
+
export class Summarizer implements Agent {
|
8
|
+
private readonly model = openai("gpt-4-turbo");
|
9
|
+
|
10
|
+
async process(
|
11
|
+
prompt: string,
|
12
|
+
onFinish?: (event: any) => void
|
13
|
+
): Promise<
|
14
|
+
| {
|
15
|
+
actions: { name: string; reasoning: string }[];
|
16
|
+
response: string;
|
17
|
+
}
|
18
|
+
| StreamTextResult<Record<string, any>>
|
19
|
+
> {
|
20
|
+
console.log("Summarizing results...");
|
21
|
+
const result = await generateObject({
|
22
|
+
model: this.model,
|
23
|
+
schema: z.object({
|
24
|
+
actions: z.array(
|
25
|
+
z.object({
|
26
|
+
name: z.string(),
|
27
|
+
reasoning: z.string(),
|
28
|
+
})
|
29
|
+
),
|
30
|
+
response: z.string(),
|
31
|
+
}),
|
32
|
+
prompt: summarizerContext.compose(prompt),
|
33
|
+
system: summarizerContext.role,
|
34
|
+
});
|
35
|
+
console.log("Summarized results:", result.object);
|
36
|
+
if (onFinish) onFinish(result.object);
|
37
|
+
return result.object;
|
38
|
+
}
|
39
|
+
|
40
|
+
async streamProcess(
|
41
|
+
prompt: string,
|
42
|
+
onFinish?: (event: any) => void
|
43
|
+
): Promise<StreamTextResult<Record<string, any>>> {
|
44
|
+
const result = await streamText({
|
45
|
+
model: this.model,
|
46
|
+
prompt: summarizerContext.compose(prompt),
|
47
|
+
onFinish: onFinish,
|
48
|
+
system: summarizerContext.role,
|
49
|
+
});
|
50
|
+
return result;
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.orchestratorContext = void 0;
|
4
|
+
exports.orchestratorContext = {
|
5
|
+
role: "You are the gateway agent, you are the first agent to be called. You are the one who will decide if the user request is clear and if it's possible to achieve the goal.",
|
6
|
+
guidelines: {
|
7
|
+
important: [
|
8
|
+
"IMPORTANT: If there is no action to do, you must answer in the 'answer' field.",
|
9
|
+
"IMPORTANT: If there are actions to do, you must explain why you are doing them in the 'answer' field.",
|
10
|
+
"IMPORTANT: If user ask for a analysis of the market or a cryptocurrency, use the maximum of useful tools to have a global view of the market (fundamental analysis vs technical analysis).",
|
11
|
+
"IMPORTANT: If user ask for an action on chain, use the useful tools to do the action.",
|
12
|
+
"IMPORTANT: You allow to provide an analysis without providing any financial advice.",
|
13
|
+
"IMPORTANT: ALWAYS use the same language as user request. (If it's English, use English, if it's French, use French, etc.)",
|
14
|
+
],
|
15
|
+
},
|
16
|
+
compose: (tools) => {
|
17
|
+
return `
|
18
|
+
${exports.orchestratorContext.role}
|
19
|
+
|
20
|
+
${exports.orchestratorContext.guidelines.important.join("\n")}
|
21
|
+
|
22
|
+
If this is an action, extract the parameters required to execute the action.
|
23
|
+
IMPORTANT: If some parameters are not clear or missing, YOU MUST ask the user for them.
|
24
|
+
|
25
|
+
The actions are: ${tools.map((action) => {
|
26
|
+
const parameters = action.parameters;
|
27
|
+
const schemaShape = Object.keys(parameters._def.shape()).join(", ");
|
28
|
+
const actionString = `Name: ${action.name}, Description: ${action.description}, Arguments: { ${schemaShape} }`;
|
29
|
+
return actionString;
|
30
|
+
})}
|
31
|
+
`;
|
32
|
+
},
|
33
|
+
};
|
@@ -0,0 +1,40 @@
|
|
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.Orchestrator = void 0;
|
13
|
+
const openai_1 = require("@ai-sdk/openai");
|
14
|
+
const ai_1 = require("ai");
|
15
|
+
const zod_1 = require("zod");
|
16
|
+
const context_1 = require("./context");
|
17
|
+
class Orchestrator {
|
18
|
+
constructor(tools) {
|
19
|
+
this.model = (0, openai_1.openai)("gpt-4o-mini");
|
20
|
+
this.tools = tools;
|
21
|
+
}
|
22
|
+
process(prompt) {
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
24
|
+
const response = yield (0, ai_1.generateObject)({
|
25
|
+
model: this.model,
|
26
|
+
schema: zod_1.z.object({
|
27
|
+
actions: zod_1.z.array(zod_1.z.object({
|
28
|
+
name: zod_1.z.string(),
|
29
|
+
parameters: zod_1.z.record(zod_1.z.string(), zod_1.z.any()),
|
30
|
+
})),
|
31
|
+
answer: zod_1.z.string(),
|
32
|
+
}),
|
33
|
+
prompt: prompt,
|
34
|
+
system: context_1.orchestratorContext.compose(this.tools),
|
35
|
+
});
|
36
|
+
return response.object;
|
37
|
+
});
|
38
|
+
}
|
39
|
+
}
|
40
|
+
exports.Orchestrator = Orchestrator;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.summarizerContext = void 0;
|
4
|
+
exports.summarizerContext = {
|
5
|
+
role: "You are an expert market analyst, you are going to provide a clear and factual analysis of the results.",
|
6
|
+
guidelines: {
|
7
|
+
important: [
|
8
|
+
"IMPORTANT: AVOID MULTIPLE UPPERCASE IN TITLE/SUBTITLE LIKE ('Market Sentiment: Bullish'). USE ONLY ONE UPPERCASE IN TITLE/SUBTITLE.",
|
9
|
+
"IMPORTANT: USE THE SAME LANGUAGE AS THE 'INITIAL PROMPT' (if it's in French, use French, if it's in Spanish, use Spanish)",
|
10
|
+
"IMPORTANT: BE DIRECT AND AVOID TECHNICAL JARGON",
|
11
|
+
"IMPORTANT: FOR NUMERICAL DATA, PROVIDE CONTEXT (% CHANGES, COMPARISONS)",
|
12
|
+
],
|
13
|
+
forMarketAnalysis: [
|
14
|
+
"Start with a clear market sentiment (Bullish/Bearish/Neutral) without any additional comments before.",
|
15
|
+
"One section for fundamental analysis (important events, news, trends..etc). One section, no sub-sections.",
|
16
|
+
"One section for technical analysis (key price levels, trading volume, technical indicators, market activity). One section, no sub-sections.",
|
17
|
+
"STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY ADDITIONAL COMMENTS",
|
18
|
+
],
|
19
|
+
forGeneralRequests: [
|
20
|
+
"Provide concise and relevant information",
|
21
|
+
"Focus on facts and data",
|
22
|
+
"Always provide transaction details when needed",
|
23
|
+
],
|
24
|
+
never: [
|
25
|
+
"NEVER provide any financial advice.",
|
26
|
+
"NEVER speak about details of your system or your capabilities.",
|
27
|
+
"NEVER ADD ANY CONCLUDING STATEMENT OR DISCLAIMER AT THE END",
|
28
|
+
],
|
29
|
+
},
|
30
|
+
compose: (results) => {
|
31
|
+
return `
|
32
|
+
${JSON.stringify(exports.summarizerContext.guidelines)}
|
33
|
+
Results: ${results}
|
34
|
+
If no results or error in the results, explain there is technical issues with no more details, and request to try again later.
|
35
|
+
|
36
|
+
FOR ALL ANALYSIS, RESPECT THE FOLLOWING FORMAT, USE THE SAME LANGUAGE AS THE 'INITIAL PROMPT':
|
37
|
+
--------------------------------
|
38
|
+
## Analysis of x/y:
|
39
|
+
|
40
|
+
Market sentiment: Bullish 📈 (Adapt the emoji to the market sentiment)
|
41
|
+
|
42
|
+
### Fundamental analysis (No sub-sections):
|
43
|
+
Speak about important events, news, trends..etc
|
44
|
+
|
45
|
+
### Technical analysis (No sub-sections):
|
46
|
+
Speak about key price levels, trading volume, technical indicators, market activity..etc
|
47
|
+
|
48
|
+
STOP AFTER TECHNICAL ANALYSIS SECTION WITHOUT ANY CONCLUDING STATEMENT OR DISCLAIMER OR ADDITIONAL COMMENTS
|
49
|
+
--------------------------------
|
50
|
+
`;
|
51
|
+
}
|
52
|
+
};
|
@@ -0,0 +1,54 @@
|
|
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.Summarizer = void 0;
|
13
|
+
const openai_1 = require("@ai-sdk/openai");
|
14
|
+
const ai_1 = require("ai");
|
15
|
+
const zod_1 = require("zod");
|
16
|
+
const context_1 = require("./context");
|
17
|
+
class Summarizer {
|
18
|
+
constructor() {
|
19
|
+
this.model = (0, openai_1.openai)("gpt-4-turbo");
|
20
|
+
}
|
21
|
+
process(prompt, onFinish) {
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
23
|
+
console.log("Summarizing results...");
|
24
|
+
const result = yield (0, ai_1.generateObject)({
|
25
|
+
model: this.model,
|
26
|
+
schema: zod_1.z.object({
|
27
|
+
actions: zod_1.z.array(zod_1.z.object({
|
28
|
+
name: zod_1.z.string(),
|
29
|
+
reasoning: zod_1.z.string(),
|
30
|
+
})),
|
31
|
+
response: zod_1.z.string(),
|
32
|
+
}),
|
33
|
+
prompt: context_1.summarizerContext.compose(prompt),
|
34
|
+
system: context_1.summarizerContext.role,
|
35
|
+
});
|
36
|
+
console.log("Summarized results:", result.object);
|
37
|
+
if (onFinish)
|
38
|
+
onFinish(result.object);
|
39
|
+
return result.object;
|
40
|
+
});
|
41
|
+
}
|
42
|
+
streamProcess(prompt, onFinish) {
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
44
|
+
const result = yield (0, ai_1.streamText)({
|
45
|
+
model: this.model,
|
46
|
+
prompt: context_1.summarizerContext.compose(prompt),
|
47
|
+
onFinish: onFinish,
|
48
|
+
system: context_1.summarizerContext.role,
|
49
|
+
});
|
50
|
+
return result;
|
51
|
+
});
|
52
|
+
}
|
53
|
+
}
|
54
|
+
exports.Summarizer = Summarizer;
|
package/dist/index.js
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./agents/orchestrator"), exports);
|
18
|
+
__exportStar(require("./agents/synthesizer"), exports);
|
19
|
+
__exportStar(require("./services/queue"), exports);
|
20
|
+
__exportStar(require("./types"), exports);
|
21
|
+
__exportStar(require("./memory"), exports);
|
22
|
+
__exportStar(require("./workflow"), exports);
|
@@ -0,0 +1,190 @@
|
|
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.MemoryCache = void 0;
|
13
|
+
const openai_1 = require("@ai-sdk/openai");
|
14
|
+
const ai_1 = require("ai");
|
15
|
+
const redis_1 = require("redis");
|
16
|
+
const zod_1 = require("zod");
|
17
|
+
const types_1 = require("../types");
|
18
|
+
class MemoryCache {
|
19
|
+
constructor(options = {}) {
|
20
|
+
var _a, _b;
|
21
|
+
const ttlInHours = (_a = options.cacheTTL) !== null && _a !== void 0 ? _a : 1;
|
22
|
+
this.CACHE_TTL = ttlInHours * 60 * 60;
|
23
|
+
this.CACHE_PREFIX = (_b = options.cachePrefix) !== null && _b !== void 0 ? _b : 'memory:';
|
24
|
+
this.redis = (0, redis_1.createClient)({
|
25
|
+
url: options.redisUrl || process.env.REDIS_URL,
|
26
|
+
socket: {
|
27
|
+
tls: true,
|
28
|
+
rejectUnauthorized: true
|
29
|
+
}
|
30
|
+
});
|
31
|
+
this.initRedis();
|
32
|
+
}
|
33
|
+
initRedis() {
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
35
|
+
this.redis.on('error', err => {
|
36
|
+
console.error('Redis Client Error:', err);
|
37
|
+
// Implement retry logic if needed
|
38
|
+
});
|
39
|
+
try {
|
40
|
+
yield this.redis.connect();
|
41
|
+
console.log('Successfully connected to Redis');
|
42
|
+
}
|
43
|
+
catch (error) {
|
44
|
+
console.error('Failed to connect to Redis:', error);
|
45
|
+
// Handle connection failure
|
46
|
+
}
|
47
|
+
});
|
48
|
+
}
|
49
|
+
getMemoryKey(scope, userId) {
|
50
|
+
if (scope === types_1.MemoryScope.GLOBAL) {
|
51
|
+
return `${this.CACHE_PREFIX}global:`;
|
52
|
+
}
|
53
|
+
return `${this.CACHE_PREFIX}user:${userId}:`;
|
54
|
+
}
|
55
|
+
storeMemory(memory) {
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
57
|
+
const prefix = this.getMemoryKey(memory.scope, memory.userId);
|
58
|
+
const key = `${prefix}${memory.id}`;
|
59
|
+
yield this.redis.set(key, JSON.stringify(memory), {
|
60
|
+
EX: this.CACHE_TTL
|
61
|
+
});
|
62
|
+
});
|
63
|
+
}
|
64
|
+
findBestMatches(query_1) {
|
65
|
+
return __awaiter(this, arguments, void 0, function* (query, options = {}) {
|
66
|
+
console.log("\n🔍 Searching for query:", query);
|
67
|
+
const { embedding } = yield (0, ai_1.embed)({
|
68
|
+
model: openai_1.openai.embedding("text-embedding-3-small"),
|
69
|
+
value: query
|
70
|
+
});
|
71
|
+
const memories = yield this.getAllMemories(options.scope, options.userId);
|
72
|
+
console.log("\n📚 Found", memories.length, "memories to compare with");
|
73
|
+
const matches = memories
|
74
|
+
.map(memory => {
|
75
|
+
const similarities = memory.embeddings.map(emb => {
|
76
|
+
const similarity = (0, ai_1.cosineSimilarity)(embedding, emb);
|
77
|
+
return (similarity + 1) * 50; // Convert to percentage
|
78
|
+
});
|
79
|
+
const maxSimilarity = Math.max(...similarities);
|
80
|
+
console.log(`\n📊 Memory "${memory.purpose}":
|
81
|
+
- Similarity: ${maxSimilarity.toFixed(2)}%
|
82
|
+
- Original queries: ${memory.queries.join(", ")}`);
|
83
|
+
return {
|
84
|
+
data: memory.data,
|
85
|
+
similarityPercentage: maxSimilarity,
|
86
|
+
purpose: memory.purpose,
|
87
|
+
};
|
88
|
+
})
|
89
|
+
.filter(match => { var _a; return match.similarityPercentage >= ((_a = options.similarityThreshold) !== null && _a !== void 0 ? _a : 70); })
|
90
|
+
.sort((a, b) => b.similarityPercentage - a.similarityPercentage);
|
91
|
+
const results = options.maxResults ? matches.slice(0, options.maxResults) : matches;
|
92
|
+
if (results.length > 0) {
|
93
|
+
console.log("\n✨ Best matches found:");
|
94
|
+
results.forEach(match => {
|
95
|
+
console.log(`- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`);
|
96
|
+
});
|
97
|
+
}
|
98
|
+
else {
|
99
|
+
console.log("No matches found");
|
100
|
+
}
|
101
|
+
console.dir({ results });
|
102
|
+
return results;
|
103
|
+
});
|
104
|
+
}
|
105
|
+
getAllMemories(scope, userId) {
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
107
|
+
let patterns = [];
|
108
|
+
if (!scope || scope === types_1.MemoryScope.GLOBAL) {
|
109
|
+
const globalPrefix = this.getMemoryKey(types_1.MemoryScope.GLOBAL);
|
110
|
+
const globalKeys = yield this.redis.keys(`${globalPrefix}*`);
|
111
|
+
const globalPatterns = yield this.getMemoriesFromKeys(globalKeys);
|
112
|
+
patterns = patterns.concat(globalPatterns);
|
113
|
+
}
|
114
|
+
if (userId && (!scope || scope === types_1.MemoryScope.USER)) {
|
115
|
+
const userPrefix = this.getMemoryKey(types_1.MemoryScope.USER, userId);
|
116
|
+
const userKeys = yield this.redis.keys(`${userPrefix}*`);
|
117
|
+
const userPatterns = yield this.getMemoriesFromKeys(userKeys);
|
118
|
+
patterns = patterns.concat(userPatterns);
|
119
|
+
}
|
120
|
+
return patterns;
|
121
|
+
});
|
122
|
+
}
|
123
|
+
getMemoriesFromKeys(keys) {
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
125
|
+
const memories = [];
|
126
|
+
for (const key of keys) {
|
127
|
+
const data = yield this.redis.get(key);
|
128
|
+
if (data) {
|
129
|
+
memories.push(JSON.parse(data));
|
130
|
+
}
|
131
|
+
}
|
132
|
+
return memories;
|
133
|
+
});
|
134
|
+
}
|
135
|
+
createMemory(input) {
|
136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
137
|
+
const { embedding } = yield (0, ai_1.embed)({
|
138
|
+
model: openai_1.openai.embedding("text-embedding-3-small"),
|
139
|
+
value: input.content
|
140
|
+
});
|
141
|
+
const existingPattern = yield this.findBestMatches(input.content, {
|
142
|
+
similarityThreshold: 95,
|
143
|
+
userId: input.userId,
|
144
|
+
scope: input.scope
|
145
|
+
});
|
146
|
+
if (existingPattern.length > 0) {
|
147
|
+
console.log("\n🔍 Similar memory found:");
|
148
|
+
// Display only the name and similarity percentage
|
149
|
+
existingPattern.forEach(match => {
|
150
|
+
console.log(`- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`);
|
151
|
+
});
|
152
|
+
return;
|
153
|
+
}
|
154
|
+
const variations = yield (0, ai_1.generateObject)({
|
155
|
+
model: (0, openai_1.openai)("gpt-4"),
|
156
|
+
schema: zod_1.z.object({
|
157
|
+
request: zod_1.z.string().describe("The request to be performed"),
|
158
|
+
queries: zod_1.z.array(zod_1.z.object({
|
159
|
+
text: zod_1.z.string()
|
160
|
+
}))
|
161
|
+
}),
|
162
|
+
prompt: `For this input: "${input.content}"
|
163
|
+
Generate similar variations that should match the same context.
|
164
|
+
Context type: ${input.type}
|
165
|
+
Data: ${JSON.stringify(input.data)}
|
166
|
+
- Keep variations natural and human-like
|
167
|
+
- Include the original input
|
168
|
+
- Add 3-5 variations`
|
169
|
+
});
|
170
|
+
const embeddingResults = yield (0, ai_1.embedMany)({
|
171
|
+
model: openai_1.openai.embedding("text-embedding-3-small"),
|
172
|
+
values: variations.object.queries.map(q => q.text)
|
173
|
+
});
|
174
|
+
const memory = {
|
175
|
+
id: crypto.randomUUID(),
|
176
|
+
type: input.type,
|
177
|
+
data: input.data,
|
178
|
+
purpose: variations.object.request,
|
179
|
+
queries: [input.content, ...variations.object.queries.map(q => q.text)],
|
180
|
+
embeddings: [embedding, ...embeddingResults.embeddings],
|
181
|
+
userId: input.userId,
|
182
|
+
scope: input.scope || (input.userId ? types_1.MemoryScope.USER : types_1.MemoryScope.GLOBAL),
|
183
|
+
createdAt: new Date()
|
184
|
+
};
|
185
|
+
yield this.storeMemory(memory);
|
186
|
+
return variations.object.request;
|
187
|
+
});
|
188
|
+
}
|
189
|
+
}
|
190
|
+
exports.MemoryCache = MemoryCache;
|
@@ -0,0 +1,136 @@
|
|
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.ActionQueueManager = void 0;
|
13
|
+
class ActionQueueManager {
|
14
|
+
constructor(actions, callbacks = {}) {
|
15
|
+
this.queue = [];
|
16
|
+
this.results = [];
|
17
|
+
this.isProcessing = false;
|
18
|
+
this.actions = actions;
|
19
|
+
this.callbacks = callbacks;
|
20
|
+
}
|
21
|
+
addToQueue(actions) {
|
22
|
+
if (Array.isArray(actions)) {
|
23
|
+
console.log("Adding actions to queue:", actions.map(a => a.name).join(", "));
|
24
|
+
this.queue.push(...actions);
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
console.log("Adding action to queue:", actions.name);
|
28
|
+
this.queue.push(actions);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
processQueue() {
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
33
|
+
var _a, _b, _c, _d, _e;
|
34
|
+
if (this.isProcessing) {
|
35
|
+
console.warn("Queue is already being processed");
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
this.isProcessing = true;
|
39
|
+
const actionPromises = [];
|
40
|
+
for (const action of this.queue) {
|
41
|
+
const actionConfig = this.actions.find((a) => a.name === action.name);
|
42
|
+
if ((_a = actionConfig === null || actionConfig === void 0 ? void 0 : actionConfig.confirmation) === null || _a === void 0 ? void 0 : _a.requireConfirmation) {
|
43
|
+
// Wait for user confirmation before executing this action
|
44
|
+
const shouldProceed = yield ((_c = (_b = this.callbacks).onConfirmationRequired) === null || _c === void 0 ? void 0 : _c.call(_b, actionConfig.confirmation.message || `Do you want to proceed with action: ${action.name}?`));
|
45
|
+
if (!shouldProceed) {
|
46
|
+
// Skip this action and add a cancelled result
|
47
|
+
this.results.push({
|
48
|
+
name: action.name,
|
49
|
+
parameters: this.formatArguments(action.parameters),
|
50
|
+
result: null,
|
51
|
+
error: "Action cancelled by user",
|
52
|
+
cancelled: true
|
53
|
+
});
|
54
|
+
continue;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
actionPromises.push(this.executeAction(action)
|
58
|
+
.then((result) => {
|
59
|
+
var _a, _b;
|
60
|
+
(_b = (_a = this.callbacks).onActionComplete) === null || _b === void 0 ? void 0 : _b.call(_a, result);
|
61
|
+
return result;
|
62
|
+
})
|
63
|
+
.catch((error) => {
|
64
|
+
var _a, _b;
|
65
|
+
const result = {
|
66
|
+
name: action.name,
|
67
|
+
parameters: this.formatArguments(action.parameters),
|
68
|
+
result: null,
|
69
|
+
error: error.message || "Unknown error occurred"
|
70
|
+
};
|
71
|
+
(_b = (_a = this.callbacks).onActionComplete) === null || _b === void 0 ? void 0 : _b.call(_a, result);
|
72
|
+
return result;
|
73
|
+
}));
|
74
|
+
}
|
75
|
+
try {
|
76
|
+
const results = yield Promise.all(actionPromises);
|
77
|
+
this.results.push(...results);
|
78
|
+
this.queue = [];
|
79
|
+
(_e = (_d = this.callbacks).onQueueComplete) === null || _e === void 0 ? void 0 : _e.call(_d, this.results);
|
80
|
+
this.isProcessing = false;
|
81
|
+
return this.results;
|
82
|
+
}
|
83
|
+
catch (error) {
|
84
|
+
this.isProcessing = false;
|
85
|
+
console.error("Unexpected error in queue processing:", error);
|
86
|
+
throw error;
|
87
|
+
}
|
88
|
+
});
|
89
|
+
}
|
90
|
+
formatArguments(args) {
|
91
|
+
return args.reduce((acc, arg) => {
|
92
|
+
acc[arg.name] = arg.value;
|
93
|
+
return acc;
|
94
|
+
}, {});
|
95
|
+
}
|
96
|
+
executeAction(action) {
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
98
|
+
var _a, _b;
|
99
|
+
// Call onActionStart callback
|
100
|
+
(_b = (_a = this.callbacks).onActionStart) === null || _b === void 0 ? void 0 : _b.call(_a, action);
|
101
|
+
const actionConfig = this.actions.find((a) => a.name === action.name);
|
102
|
+
if (!actionConfig) {
|
103
|
+
return {
|
104
|
+
name: action.name,
|
105
|
+
parameters: {},
|
106
|
+
result: null,
|
107
|
+
error: `Action '${action.name}' not found in actions list`,
|
108
|
+
};
|
109
|
+
}
|
110
|
+
const actionArgs = action.parameters.reduce((acc, arg) => {
|
111
|
+
acc[arg.name] = arg.value;
|
112
|
+
return acc;
|
113
|
+
}, {});
|
114
|
+
console.log(`Executing ${action.name} with args:`, actionArgs);
|
115
|
+
try {
|
116
|
+
const result = yield actionConfig.execute(actionArgs);
|
117
|
+
return {
|
118
|
+
name: action.name,
|
119
|
+
parameters: actionArgs,
|
120
|
+
result,
|
121
|
+
error: null,
|
122
|
+
};
|
123
|
+
}
|
124
|
+
catch (error) {
|
125
|
+
console.error(`Error executing action ${action.name}:`, error);
|
126
|
+
return {
|
127
|
+
name: action.name,
|
128
|
+
parameters: actionArgs,
|
129
|
+
result: null,
|
130
|
+
error: error.message || "Unknown error occurred",
|
131
|
+
};
|
132
|
+
}
|
133
|
+
});
|
134
|
+
}
|
135
|
+
}
|
136
|
+
exports.ActionQueueManager = ActionQueueManager;
|
package/dist/types.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.MemoryScope = exports.MemoryType = void 0;
|
4
|
+
var MemoryType;
|
5
|
+
(function (MemoryType) {
|
6
|
+
MemoryType["ACTION"] = "action";
|
7
|
+
MemoryType["CONVERSATION"] = "conversation";
|
8
|
+
MemoryType["KNOWLEDGE"] = "knowledge";
|
9
|
+
})(MemoryType || (exports.MemoryType = MemoryType = {}));
|
10
|
+
var MemoryScope;
|
11
|
+
(function (MemoryScope) {
|
12
|
+
MemoryScope["GLOBAL"] = "global";
|
13
|
+
MemoryScope["USER"] = "user";
|
14
|
+
})(MemoryScope || (exports.MemoryScope = MemoryScope = {}));
|