@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.
@@ -0,0 +1,26 @@
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
+ var _a;
13
+ const firstMatch = (_a = similarActions === null || similarActions === void 0 ? void 0 : similarActions[0]) === null || _a === void 0 ? void 0 : _a.data;
14
+ return firstMatch === null || firstMatch === void 0 ? void 0 : firstMatch.map((action) => QueueItemTransformer.transformActionToQueueItem(action));
15
+ }
16
+ static transformParameters(parameters) {
17
+ return Object.entries(parameters).map(([name, value]) => ({
18
+ name,
19
+ value: typeof value === 'object' ? JSON.stringify(value) : String(value)
20
+ }));
21
+ }
22
+ static transformActionsToQueueItems(actions) {
23
+ return actions === null || actions === void 0 ? void 0 : actions.map(action => this.transformActionToQueueItem(action));
24
+ }
25
+ }
26
+ exports.QueueItemTransformer = QueueItemTransformer;
@@ -0,0 +1,187 @@
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.Workflow = void 0;
13
+ const synthesizer_1 = require("../agents/synthesizer");
14
+ const queue_1 = require("../services/queue");
15
+ const types_1 = require("../types");
16
+ const queue_item_transformer_1 = require("../utils/queue-item-transformer");
17
+ class Workflow {
18
+ constructor(user, dependencies) {
19
+ this.user = user;
20
+ this.dependencies = dependencies;
21
+ this.CONFIRMATION_TIMEOUT = 5 * 60 * 1000; // 5 minutes
22
+ this.SIMILARITY_THRESHOLD = 95;
23
+ this.MAX_RESULTS = 1;
24
+ }
25
+ start(prompt, promptWithContext, stream) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ const request = yield this.dependencies.orchestrator.process(promptWithContext);
28
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
29
+ type: "on-message",
30
+ data: request,
31
+ });
32
+ if (request.actions.length > 0) {
33
+ return this.handleActions(prompt, request.actions);
34
+ }
35
+ });
36
+ }
37
+ handleActions(prompt, actions) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ let predefinedActions = actions;
40
+ console.log("\nšŸ” Predefined actions:", predefinedActions);
41
+ const similarActions = yield this.dependencies.memoryCache.findBestMatches(prompt, {
42
+ similarityThreshold: this.SIMILARITY_THRESHOLD,
43
+ maxResults: this.MAX_RESULTS,
44
+ userId: this.user.id,
45
+ scope: types_1.MemoryScope.USER,
46
+ });
47
+ console.log("\nšŸ” Similar actions:", similarActions);
48
+ predefinedActions =
49
+ queue_item_transformer_1.QueueItemTransformer.transformActionsToQueueItems(predefinedActions) ||
50
+ [];
51
+ console.log("\nšŸ” Transformed predefined actions:", predefinedActions);
52
+ if (similarActions && similarActions.length > 0) {
53
+ predefinedActions =
54
+ queue_item_transformer_1.QueueItemTransformer.transformFromSimilarActions(similarActions) || [];
55
+ console.log("\nšŸ” Transformed similar actions:", predefinedActions);
56
+ }
57
+ console.log("\nšŸ” Final actions:", predefinedActions);
58
+ const callbacks = this.createCallbacks(prompt, similarActions);
59
+ console.log("\nšŸ” Queue prepared");
60
+ const actionsResult = yield this.executeActions(predefinedActions, this.dependencies.orchestrator.tools, callbacks);
61
+ console.log("\nšŸ” Actions result:", actionsResult);
62
+ return this.handleActionResults(Object.assign(Object.assign({}, actionsResult), { initialPrompt: prompt }), prompt);
63
+ });
64
+ }
65
+ executeActions(predefinedActions, tools, callbacks) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ try {
68
+ const queueManager = new queue_1.ActionQueueManager(tools, {
69
+ onActionStart: callbacks === null || callbacks === void 0 ? void 0 : callbacks.onActionStart,
70
+ onActionComplete: callbacks === null || callbacks === void 0 ? void 0 : callbacks.onActionComplete,
71
+ onQueueComplete: callbacks === null || callbacks === void 0 ? void 0 : callbacks.onQueueComplete,
72
+ onConfirmationRequired: (message) => __awaiter(this, void 0, void 0, function* () {
73
+ if (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onConfirmationRequired) {
74
+ return yield callbacks.onConfirmationRequired(message);
75
+ }
76
+ return false;
77
+ }),
78
+ });
79
+ queueManager.addToQueue(predefinedActions);
80
+ if (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onQueueStart) {
81
+ callbacks.onQueueStart(predefinedActions);
82
+ }
83
+ console.log("Processing queue...");
84
+ const results = yield queueManager.processQueue();
85
+ console.log("Queue completed:");
86
+ console.dir(results, { depth: null });
87
+ return {
88
+ type: "success",
89
+ data: results || [],
90
+ };
91
+ }
92
+ catch (error) {
93
+ console.error("Error processing prompt:", error);
94
+ throw error;
95
+ }
96
+ });
97
+ }
98
+ createCallbacks(prompt, similarActions) {
99
+ return {
100
+ onQueueStart: (actions) => __awaiter(this, void 0, void 0, function* () {
101
+ console.dir(actions, { depth: null });
102
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
103
+ type: "queue-start",
104
+ actions,
105
+ });
106
+ }),
107
+ onActionStart: (action) => {
108
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
109
+ type: "action-start",
110
+ action: action.name,
111
+ args: action.parameters,
112
+ });
113
+ },
114
+ onActionComplete: (action) => {
115
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
116
+ type: "action-complete",
117
+ action: action.name,
118
+ result: action.result,
119
+ });
120
+ },
121
+ onQueueComplete: (actions) => __awaiter(this, void 0, void 0, function* () {
122
+ if (!similarActions.length) {
123
+ yield this.saveToMemory(prompt, actions);
124
+ }
125
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
126
+ type: "queue-complete",
127
+ });
128
+ }),
129
+ onConfirmationRequired: this.handleConfirmationRequest.bind(this),
130
+ };
131
+ }
132
+ handleConfirmationRequest(message) {
133
+ return __awaiter(this, void 0, void 0, function* () {
134
+ return new Promise((resolve) => {
135
+ const confirmationId = Date.now().toString();
136
+ const handleConfirmation = (data) => {
137
+ if (data.confirmationId === confirmationId) {
138
+ this.dependencies.eventEmitter.removeListener("confirmation-response", handleConfirmation);
139
+ resolve(data.confirmed);
140
+ }
141
+ };
142
+ this.dependencies.eventEmitter.once("confirmation-response", handleConfirmation);
143
+ this.dependencies.eventEmitter.emit("orchestrator-update", {
144
+ type: "confirmation-required",
145
+ id: confirmationId,
146
+ message,
147
+ });
148
+ setTimeout(() => {
149
+ this.dependencies.eventEmitter.removeListener("confirmation-response", handleConfirmation);
150
+ resolve(false);
151
+ }, this.CONFIRMATION_TIMEOUT);
152
+ });
153
+ });
154
+ }
155
+ saveToMemory(prompt, actions) {
156
+ return __awaiter(this, void 0, void 0, function* () {
157
+ console.log("\nšŸ” Creating memory...");
158
+ yield this.dependencies.memoryCache.createMemory({
159
+ content: prompt,
160
+ userId: this.user.id,
161
+ scope: types_1.MemoryScope.USER,
162
+ type: types_1.MemoryType.ACTION,
163
+ data: actions,
164
+ });
165
+ });
166
+ }
167
+ handleActionResults(actionsResult_1, prompt_1) {
168
+ return __awaiter(this, arguments, void 0, function* (actionsResult, prompt, stream = true) {
169
+ if (!this.hasNonPrepareActions(actionsResult.data)) {
170
+ return;
171
+ }
172
+ const summarizer = new synthesizer_1.Summarizer();
173
+ const summaryData = JSON.stringify({
174
+ result: actionsResult.data,
175
+ initialPrompt: prompt,
176
+ });
177
+ return stream
178
+ ? (yield summarizer.streamProcess(summaryData)).toDataStreamResponse()
179
+ : yield summarizer.process(summaryData);
180
+ });
181
+ }
182
+ hasNonPrepareActions(actions) {
183
+ return (Array.isArray(actions) &&
184
+ actions.some((action) => { var _a; return ((_a = action.name) === null || _a === void 0 ? void 0 : _a.split("-")[0]) !== "prepare"; }));
185
+ }
186
+ }
187
+ exports.Workflow = Workflow;
package/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./agents/orchestrator";
2
+ export * from "./agents/synthesizer";
3
+ export * from "./services/queue";
4
+ export * from "./types";
5
+
6
+ export * from "./memory";
7
+ export * from "./workflow";
@@ -0,0 +1,201 @@
1
+ import { openai } from "@ai-sdk/openai";
2
+ import { cosineSimilarity, embed, embedMany, generateObject } from "ai";
3
+ import { createClient } from 'redis';
4
+ import { z } from "zod";
5
+ import { CreateMemoryInput, MatchOptions, Memory, MemoryCacheOptions, MemoryScope } from "../types";
6
+
7
+ export class MemoryCache {
8
+ private redis;
9
+ private readonly CACHE_PREFIX: string;
10
+ private readonly CACHE_TTL: number;
11
+
12
+ constructor(options: MemoryCacheOptions = {}) {
13
+ const ttlInHours = options.cacheTTL ?? 1;
14
+ this.CACHE_TTL = ttlInHours * 60 * 60;
15
+ this.CACHE_PREFIX = options.cachePrefix ?? 'memory:';
16
+
17
+ this.redis = createClient({
18
+ url: options.redisUrl || process.env.REDIS_URL,
19
+ socket: {
20
+ tls: true,
21
+ rejectUnauthorized: true
22
+ }
23
+ });
24
+ this.initRedis();
25
+ }
26
+
27
+ private async initRedis() {
28
+ this.redis.on('error', err => {
29
+ console.error('Redis Client Error:', err);
30
+ // Implement retry logic if needed
31
+ });
32
+
33
+ try {
34
+ await this.redis.connect();
35
+ console.log('Successfully connected to Redis');
36
+ } catch (error) {
37
+ console.error('Failed to connect to Redis:', error);
38
+ // Handle connection failure
39
+ }
40
+ }
41
+
42
+ private getMemoryKey(scope: MemoryScope, userId?: string): string {
43
+ if (scope === MemoryScope.GLOBAL) {
44
+ return `${this.CACHE_PREFIX}global:`;
45
+ }
46
+ return `${this.CACHE_PREFIX}user:${userId}:`;
47
+ }
48
+
49
+ private async storeMemory(memory: Memory) {
50
+ const prefix = this.getMemoryKey(memory.scope, memory.userId);
51
+ const key = `${prefix}${memory.id}`;
52
+ await this.redis.set(key, JSON.stringify(memory), {
53
+ EX: this.CACHE_TTL
54
+ });
55
+ }
56
+
57
+ async findBestMatches(
58
+ query: string,
59
+ options: MatchOptions & { userId?: string; scope?: MemoryScope } = {}
60
+ ): Promise<{
61
+ data: any;
62
+ similarityPercentage: number;
63
+ purpose: string;
64
+ }[]> {
65
+ console.log("\nšŸ” Searching for query:", query);
66
+
67
+ const { embedding } = await embed({
68
+ model: openai.embedding("text-embedding-3-small"),
69
+ value: query
70
+ });
71
+
72
+ const memories = await this.getAllMemories(options.scope, options.userId);
73
+ console.log("\nšŸ“š Found", memories.length, "memories to compare with");
74
+
75
+ const matches = memories
76
+ .map(memory => {
77
+ const similarities = memory.embeddings.map(emb => {
78
+ const similarity = cosineSimilarity(embedding, emb);
79
+
80
+ return (similarity + 1) * 50; // Convert to percentage
81
+ });
82
+
83
+ const maxSimilarity = Math.max(...similarities);
84
+ console.log(`\nšŸ“Š Memory "${memory.purpose}":
85
+ - Similarity: ${maxSimilarity.toFixed(2)}%
86
+ - Original queries: ${memory.queries.join(", ")}`);
87
+
88
+ return {
89
+ data: memory.data,
90
+ similarityPercentage: maxSimilarity,
91
+ purpose: memory.purpose,
92
+ };
93
+ })
94
+ .filter(match => match.similarityPercentage >= (options.similarityThreshold ?? 70))
95
+ .sort((a, b) => b.similarityPercentage - a.similarityPercentage);
96
+
97
+ const results = options.maxResults ? matches.slice(0, options.maxResults) : matches;
98
+
99
+ if (results.length > 0) {
100
+ console.log("\n✨ Best matches found:");
101
+ results.forEach(match => {
102
+ console.log(`- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`);
103
+ });
104
+ } else {
105
+ console.log("No matches found");
106
+ }
107
+
108
+ console.dir({results});
109
+ return results;
110
+ }
111
+
112
+ private async getAllMemories(scope?: MemoryScope, userId?: string): Promise<Memory[]> {
113
+ let patterns: Memory[] = [];
114
+
115
+ if (!scope || scope === MemoryScope.GLOBAL) {
116
+ const globalPrefix = this.getMemoryKey(MemoryScope.GLOBAL);
117
+ const globalKeys = await this.redis.keys(`${globalPrefix}*`);
118
+ const globalPatterns = await this.getMemoriesFromKeys(globalKeys);
119
+ patterns = patterns.concat(globalPatterns);
120
+ }
121
+
122
+ if (userId && (!scope || scope === MemoryScope.USER)) {
123
+ const userPrefix = this.getMemoryKey(MemoryScope.USER, userId);
124
+ const userKeys = await this.redis.keys(`${userPrefix}*`);
125
+ const userPatterns = await this.getMemoriesFromKeys(userKeys);
126
+ patterns = patterns.concat(userPatterns);
127
+ }
128
+
129
+ return patterns;
130
+ }
131
+
132
+ private async getMemoriesFromKeys(keys: string[]): Promise<Memory[]> {
133
+ const memories: Memory[] = [];
134
+ for (const key of keys) {
135
+ const data = await this.redis.get(key);
136
+ if (data) {
137
+ memories.push(JSON.parse(data));
138
+ }
139
+ }
140
+ return memories;
141
+ }
142
+
143
+ public async createMemory(input: CreateMemoryInput): Promise<string | undefined> {
144
+ const { embedding } = await embed({
145
+ model: openai.embedding("text-embedding-3-small"),
146
+ value: input.content
147
+ });
148
+
149
+ const existingPattern = await this.findBestMatches(input.content, {
150
+ similarityThreshold: 95,
151
+ userId: input.userId,
152
+ scope: input.scope
153
+ });
154
+
155
+ if (existingPattern.length > 0) {
156
+ console.log("\nšŸ” Similar memory found:");
157
+ // Display only the name and similarity percentage
158
+ existingPattern.forEach(match => {
159
+ console.log(`- ${match.purpose} (${match.similarityPercentage.toFixed(2)}%)`);
160
+ });
161
+ return;
162
+ }
163
+
164
+ const variations = await generateObject({
165
+ model: openai("gpt-4"),
166
+ schema: z.object({
167
+ request: z.string().describe("The request to be performed"),
168
+ queries: z.array(z.object({
169
+ text: z.string()
170
+ }))
171
+ }),
172
+ prompt: `For this input: "${input.content}"
173
+ Generate similar variations that should match the same context.
174
+ Context type: ${input.type}
175
+ Data: ${JSON.stringify(input.data)}
176
+ - Keep variations natural and human-like
177
+ - Include the original input
178
+ - Add 3-5 variations`
179
+ });
180
+
181
+ const embeddingResults = await embedMany({
182
+ model: openai.embedding("text-embedding-3-small"),
183
+ values: variations.object.queries.map(q => q.text)
184
+ });
185
+
186
+ const memory: Memory = {
187
+ id: crypto.randomUUID(),
188
+ type: input.type,
189
+ data: input.data,
190
+ purpose: variations.object.request,
191
+ queries: [input.content, ...variations.object.queries.map(q => q.text)],
192
+ embeddings: [embedding, ...embeddingResults.embeddings],
193
+ userId: input.userId,
194
+ scope: input.scope || (input.userId ? MemoryScope.USER : MemoryScope.GLOBAL),
195
+ createdAt: new Date()
196
+ };
197
+
198
+ await this.storeMemory(memory);
199
+ return variations.object.request;
200
+ }
201
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@ai.ntellect/core",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "scripts": {
7
+ "build": "rm -rf dist && tsc",
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "Lorcann Rauzduel",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "@ai-sdk/openai": "1.0.6",
15
+ "ai": "^3.0.0",
16
+ "redis": "^4.7.0",
17
+ "zod": "^3.24.1"
18
+ },
19
+ "devDependencies": {
20
+ "typescript": "^5.7.2"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/ai.ntellect/core.git"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/ai.ntellect/core/issues"
28
+ },
29
+ "homepage": "https://github.com/ai.ntellect/core#readme"
30
+ }
@@ -0,0 +1,147 @@
1
+ import {
2
+ ActionSchema,
3
+ QueueCallbacks,
4
+ QueueItem,
5
+ QueueItemParameter,
6
+ QueueResult,
7
+ } from "../types";
8
+
9
+ export class ActionQueueManager {
10
+ private queue: QueueItem[] = [];
11
+ private results: QueueResult[] = [];
12
+ private callbacks: QueueCallbacks;
13
+ private actions: ActionSchema[];
14
+ private isProcessing: boolean = false;
15
+
16
+ constructor(actions: ActionSchema[], callbacks: QueueCallbacks = {}) {
17
+ this.actions = actions;
18
+ this.callbacks = callbacks;
19
+ }
20
+
21
+ addToQueue(actions: QueueItem | QueueItem[]) {
22
+ if (Array.isArray(actions)) {
23
+ console.log(
24
+ "Adding actions to queue:",
25
+ actions.map((a) => a.name).join(", ")
26
+ );
27
+ this.queue.push(...actions);
28
+ } else {
29
+ console.log("Adding action to queue:", actions.name);
30
+ this.queue.push(actions);
31
+ }
32
+ }
33
+
34
+ async processQueue() {
35
+ if (this.isProcessing) {
36
+ console.warn("Queue is already being processed");
37
+ return;
38
+ }
39
+
40
+ this.isProcessing = true;
41
+ const actionPromises = [];
42
+
43
+ for (const action of this.queue) {
44
+ const actionConfig = this.actions.find((a) => a.name === action.name);
45
+
46
+ if (actionConfig?.confirmation?.requireConfirmation) {
47
+ // Wait for user confirmation before executing this action
48
+ const shouldProceed = await this.callbacks.onConfirmationRequired?.(
49
+ actionConfig.confirmation.message ||
50
+ `Do you want to proceed with action: ${action.name}?`
51
+ );
52
+
53
+ if (!shouldProceed) {
54
+ // Skip this action and add a cancelled result
55
+ this.results.push({
56
+ name: action.name,
57
+ parameters: this.formatArguments(action.parameters),
58
+ result: null,
59
+ error: "Action cancelled by user",
60
+ cancelled: true,
61
+ });
62
+ continue;
63
+ }
64
+ }
65
+
66
+ actionPromises.push(
67
+ this.executeAction(action)
68
+ .then((result) => {
69
+ this.callbacks.onActionComplete?.(result);
70
+ return result;
71
+ })
72
+ .catch((error) => {
73
+ const result = {
74
+ name: action.name,
75
+ parameters: this.formatArguments(action.parameters),
76
+ result: null,
77
+ error: error.message || "Unknown error occurred",
78
+ };
79
+ this.callbacks.onActionComplete?.(result);
80
+ return result;
81
+ })
82
+ );
83
+ }
84
+
85
+ try {
86
+ const results = await Promise.all(actionPromises);
87
+ this.results.push(...results);
88
+ this.queue = [];
89
+ this.callbacks.onQueueComplete?.(this.results);
90
+ this.isProcessing = false;
91
+ return this.results;
92
+ } catch (error) {
93
+ this.isProcessing = false;
94
+ console.error("Unexpected error in queue processing:", error);
95
+ throw error;
96
+ }
97
+ }
98
+
99
+ private formatArguments(args: QueueItemParameter[]): Record<string, string> {
100
+ return args.reduce<Record<string, string>>((acc, arg) => {
101
+ acc[arg.name] = arg.value;
102
+ return acc;
103
+ }, {});
104
+ }
105
+
106
+ private async executeAction(action: QueueItem): Promise<QueueResult> {
107
+ // Call onActionStart callback
108
+ this.callbacks.onActionStart?.(action);
109
+ const actionConfig = this.actions.find((a) => a.name === action.name);
110
+ if (!actionConfig) {
111
+ return {
112
+ name: action.name,
113
+ parameters: {},
114
+ result: null,
115
+ error: `Action '${action.name}' not found in actions list`,
116
+ };
117
+ }
118
+
119
+ const actionArgs = action.parameters.reduce<Record<string, string>>(
120
+ (acc: Record<string, string>, arg: QueueItemParameter) => {
121
+ acc[arg.name] = arg.value;
122
+ return acc;
123
+ },
124
+ {}
125
+ );
126
+
127
+ console.log(`Executing ${action.name} with args:`, actionArgs);
128
+
129
+ try {
130
+ const result = await actionConfig.execute(actionArgs);
131
+ return {
132
+ name: action.name,
133
+ parameters: actionArgs,
134
+ result,
135
+ error: null,
136
+ };
137
+ } catch (error) {
138
+ console.error(`Error executing action ${action.name}:`, error);
139
+ return {
140
+ name: action.name,
141
+ parameters: actionArgs,
142
+ result: null,
143
+ error: (error as Error).message || "Unknown error occurred",
144
+ };
145
+ }
146
+ }
147
+ }