taskforce-aiagent
Version:
TaskForce is a modular, open-source, production-ready TypeScript agent framework for orchestrating AI agents, LLM-powered autonomous agents, task pipelines, dynamic toolchains, RAG workflows and memory/retrieval systems.
86 lines (85 loc) • 3.61 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonFileVectorMemoryProvider = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const embedding_js_1 = require("../../utils/embedding.js");
const log_helper_js_1 = require("../../../helpers/log.helper.js");
const chalk_1 = __importDefault(require("chalk"));
const enum_js_1 = require("../../../configs/enum.js");
const summarize_helper_js_1 = require("../../../helpers/summarize.helper.js");
const dotenv_1 = __importDefault(require("dotenv"));
const helper_js_1 = require("../../../helpers/helper.js");
dotenv_1.default.config();
class JsonFileVectorMemoryProvider {
constructor(embeddingProvider, dbPath) {
this.records = [];
this.embeddingProvider = embeddingProvider;
this.dbPath = path_1.default.resolve(dbPath ?? process.env.VECTOR_MEMORY_DB_PATH ?? "taskforce-db/memory.json");
this.loadFromFile();
}
loadFromFile() {
if (fs_1.default.existsSync(this.dbPath)) {
const raw = fs_1.default.readFileSync(this.dbPath, "utf-8");
this.records = JSON.parse(raw);
}
}
saveToFile() {
const dir = path_1.default.dirname(this.dbPath);
if (!fs_1.default.existsSync(dir)) {
fs_1.default.mkdirSync(dir, { recursive: true });
}
fs_1.default.writeFileSync(this.dbPath, JSON.stringify(this.records, null, 2), "utf-8");
}
async storeMemory(record) {
this.loadFromFile();
const vector = await this.embeddingProvider.getEmbedding(record.output);
const normalizedInput = (0, helper_js_1.normalizeInput)(record.input);
(0, log_helper_js_1.TFLog)(`🧠 [MemoryStore] task=${record.taskId}, agent=${record.metadata?.agent}, outputHash=${record.output.slice(0, 20)}, inputPreview=${normalizedInput.slice(0, 50)}`, chalk_1.default.cyan);
const isDuplicate = this.records.some((r) => {
const similarity = (0, embedding_js_1.cosineSimilarity)(vector, r.vector);
return (r.taskId === record.taskId &&
r.metadata?.agent === record.metadata?.agent &&
similarity > 0.95);
});
if (isDuplicate)
return;
const summary = await (0, summarize_helper_js_1.generateMemorySummary)(record.output);
const embedded = {
...record,
input: normalizedInput,
summary,
vector,
};
this.records.push(embedded);
this.saveToFile();
}
async loadRelevantMemory(query, limit = 3) {
const queryVec = await this.embeddingProvider.getEmbedding(query);
const filteredRecords = this.records.filter((r) => r.metadata?.agent && r.taskId);
return filteredRecords
.map((r) => ({
score: (0, embedding_js_1.cosineSimilarity)(queryVec, r.vector),
record: r,
}))
.sort((a, b) => b.score - a.score)
.slice(0, limit)
.map((r) => r.record);
}
async clearMemory(filter) {
if (!filter?.taskId) {
this.records = [];
}
else {
this.records = this.records.filter((r) => r.taskId !== filter.taskId);
}
this.saveToFile();
}
getMemoryScope() {
return enum_js_1.MemoryScope.Long;
}
}
exports.JsonFileVectorMemoryProvider = JsonFileVectorMemoryProvider;