UNPKG

@indra.ai/deva.data

Version:

The Data Deva manages data ensuring in the Deva.world ecosystem.

569 lines (531 loc) 18.3 kB
"use strict"; // Data Deva // Copyright ©2000-2026 Quinn A Michaels; All rights reserved. // Legal Signature Required For Lawful Use. // Distributed under VLA:56832904524996289116 LICENSE.md // Sunday, January 4, 2026 - 4:11:40 PM // Data Deva import Deva from '@indra.ai/deva'; import { MongoClient, ObjectId } from 'mongodb'; import pkg from './package.json' with {type:'json'}; const {agent, vars} = pkg.data; // set the __dirname import {dirname} from 'node:path'; import {fileURLToPath} from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const info = { id: pkg.id, name: pkg.name, version: pkg.version, author: pkg.author, describe: pkg.description, dir: __dirname, url: pkg.homepage, git: pkg.repository.url, bugs: pkg.bugs.url, license: pkg.license, VLA: pkg.VLA, copyright: pkg.copyright }; const DataDeva = new Deva({ info, agent, vars, utils: { translate(input) {return input.trim();}, parse(input) {return input.trim();}, process(input) {return input.trim();}, memory(input) { input = input.replace(/\n/g, ' ') .replace(/(\b)or have specific questions about it(\b)/g, '$2') .replace(/(\b), feel free to ask(\b)/g, '$2') .replace(/\sIf you have .+ free share!/g, '') .replace(/\sIf there are .+ free share!/g, '') .replace(/\s{2,}/g, ' '); return input; } }, listeners: { async 'data:history'(packet) { this.context('history', `${packet.a.agent.key}:${packet.id.uid}`); // here we insert a history object into the database. this.func.insert({ collection: 'history', data: this.lib.copy(packet), }); }, async 'data:memory'(packet) { const data = { id: packet.id, client: packet.client.id, agent: packet.agent.id, q: this.utils.memory(packet.q), a: this.utils.memory(packet.a), created: Date.now(), } data.hash = this.hash(data); await this.func.insert({ collection: `memory_${packet.agent.key}`, data, }); } }, modules: { client: false, }, devas: {}, func: { /************** func: insert params: opts describe: the insert function that inserts into the specified collection. ***************/ async insert(opts) { this.belief('data', `uid:${opts.data.id.uid}`); this.action('func', `insert:${opts.collection}:${opts.data.id.uid}`); let result = false; try { this.state('insert', `${opts.collection}:${opts.data.id.uid}`); this.state('connect', `${opts.collection}:${opts.data.id.uid}`); await this.modules.client.connect(); // connect to the database client. const db = this.modules.client.db(opts.database); // set the database to use result = await db.collection(opts.collection).insertOne(opts.data); // insert the data } finally { await this.modules.client.close(); // close the connection when done this.action('return', `insert:${opts.collection}:${opts.data.id.uid}`); this.state('valid', `insert:${opts.collection}:${opts.data.id.uid}`); this.intent('good', `insert:${opts.collection}:${opts.data.id.uid}`); this.belief('vedic', `uid:${opts.data.id.uid}`); return result; // return the result to the requestor. } }, /************** func: update params: opts describe: the update function that update into the specified collection. ***************/ async update(opts) { this.action('func', 'update'); let result = false; try { this.state('update', opts.collection); await this.modules.client.connect(); // connect to the database client. const db = this.modules.client.db(this.vars.database); // set the database to use result = await db.collection(opts.collection).updateOne( { _id: new ObjectId(`${opts.id}`) }, { $set: opts.data } ); // insert the data } finally { await this.modules.client.close(); // close the connection when done this.state('return', 'update'); return result; // return the result to the requestor. } }, /************** func: list params: obj - the find object describe: return a find from the database collection. ***************/ async list(opts={}) { this.action('func', 'list'); let result = false; const {collection,data} = opts; try { await this.modules.client.connect(); const db = this.modules.client.db(this.vars.database); result = await db.collection(collection).find(data).sort({created:1}).toArray(); } finally { await this.modules.client.close(); return result; } }, /************** func: search params: obj - the search object describe: return a search from the database collection. ***************/ async search(opts) { this.action('func', 'search'); let result = false; try { this.state('search', opts.text); const {collection,limit} = this.vars.search; await this.modules.client.connect(); const db = this.modules.client.db(this.vars.database); const table = db.collection(collection); // await table.dropIndex('a.text_1'); // const newIndex = await table.createIndex({"a.text": "text"}); const idx = await table.listIndexes().toArray(); // Print the list of indexes // console.log("Existing indexes:\n", idx); const query = {$text:{$search:opts.text}}; const projection = { _id: 0, a: { id: 1, text: 1 }, score: { $meta: "textScore" } }; result = await table.find(query).project(projection).limit(limit).toArray(); } finally { await this.modules.client.close(); this.state('return', 'search'); return result; } }, /************** func: memory params: obj - the memory object describe: return a search from the memory collection. ***************/ async memory(opts) { this.action('func', 'memory'); let result = false; const {collection,limit} = this.vars.memory; try { this.state('get', `memory`); const {database} = this.data().personal.mongo; await this.modules.client.connect(); const db = this.modules.client.db(database); const table = db.collection(collection); // await table.dropIndex('a_text_q_text'); const idx = await table.listIndexes().toArray(); const hasIdx = idx.find(i => i.name === 'a_q_text'); if (!hasIdx) { const newIdx = await table.createIndex({"a": "text", "q": "text"}, {name: 'a_q_text'}); } const query = {$text:{$search:opts.text}}; const options = { projection: { id: 1, a: 1, q: 1, score: { $meta: "textScore" }, created: 1 } }; result = await table.find(query, options).limit(parseInt(limit)).toArray(); } finally { await this.modules.client.close(); this.state('return', `memory`); return result; } }, /************** func: knowledge params: obj - the knowledge object describe: return a search from the knowledge collection. ***************/ async knowledge(opts) { this.action('func', 'knowledge'); let result = false; const {collection,limit,index} = this.vars.knowledge; try { this.state('get', 'knowledge'); const {database} = this.data().personal.mongo; await this.modules.client.connect(); const db = this.modules.client.db(database); const table = db.collection(collection); // await table.dropIndex('a_text_q_text'); const idx = await table.listIndexes().toArray(); const hasIdx = idx.find(i => i.name === index) if (!hasIdx) { const newIdx = await table.createIndex({"content": "text"}, {name: index}); } const query = {$text:{$search:opts.text}}; const options = { projection: { _id: 1, content: 1, score: { $meta: "textScore" } } }; result = await table.find(query,options).limit(parseInt(limit)).toArray(); } finally { await this.modules.client.close(); this.state('return', `knowledge`); return result; } }, /************** func: index params: opts describe: Creates an index on a collection in the database. ***************/ async indexes(opts) { this.action('func', 'indexes'); let result = false; // get indexes try { this.state('get', `indexes`); const {database} = this.data().personal.mongo; await this.modules.client.connect(); const db = this.modules.client.db(database); result = await db.collection(opts.collection).listIndexes().toArray(); } finally { await this.modules.client.close(); this.state('return', 'indexes'); return result; } }, /************** func: history params: opts describe: return history ***************/ async history() { this.action('func', 'history'); let result = false; const {collection,limit} = this.vars.history; try { this.state('get', `history`); const {database} = this.data().personal.mongo; await this.modules.client.connect(); const db = this.modules.client.db(database); result = await db.collection(collection).find({}).sort({created:-1}).limit(limit).toArray(); } finally { await this.modules.client.close(); this.state('return', `history`); return result; } }, }, methods: { /************** method: insert params: packet describe: insert data into the data vault. ***************/ insert(packet) { this.context('insert', `${packet.q.meta.params[1]}:${packet.id.uid}`); this.action('method', `insert:${packet.q.meta.params[1]}:${packet.id.uid}`); return new Promise((resolve, reject) => { const {data, meta} = packet.q; const collection = meta.params[1]; const database = meta.params[2] || this.vars.database; this.func.insert({database, collection,data}).then(ins => { this.action('resolve', `insert:${collection}:${ins.insertedId}`) return resolve({ text: `id:${ins.insertedId}`, html: `id:${ins.insertedId}`, data: ins, }); }).catch(err => { this.action('reject', 'insert'); return this.error(packet, err, reject); }); }); }, /************** method: history params: packet describe: get history ***************/ history(packet) { this.context('history', packet.id.uid); return new Promise((resolve, reject) => { this.func.history().then(history => { return resolve({ text: 'see data', html: 'see data', data: history, }) }).catch(err => { return this.error(packet, err, reject); }); }); }, /************** method: history params: packet describe: get history ***************/ search(packet) { this.context('search', packet.q.text); this.action('method', `search:${packet.q.text}`); return new Promise((resolve, reject) => { if (!packet.q.text) return resolve(this._messages.notext); const {params} = packet.q.meta; if (params[1]) this.vars.search.collection = packet.q.meta.params[1]; if (params[2]) this.vars.search.limit = packet.q.meta.params[2]; this.func.search(packet.q).then(search => { this.state('resolve', `search:${packet.q.text}`); return resolve({ text: 'see data', html: 'see data', data: search, }) }).catch(err => { return this.error(packet, err, reject); }); }); }, /************** method: memory params: packet describe: search memory ***************/ memory(packet) { this.context('memory', packet.q.text); this.action('method', `memory`); return new Promise((resolve, reject) => { if (!packet.q.text) return resolve(this._messages.notext); const {params} = packet.q.meta; const data = {}; if (params[1]) this.vars.memory.collection = `memory_${params[1]}`; if (params[2]) this.vars.memory.limit = packet.q.meta.params[2]; this.func.memory(packet.q).then(memory => { data.memory = memory; const text = memory ? memory.map(mem => { return [ `::begin:memory:${mem.id}`, `question: ${mem.q}`, `answer: ${mem.a}`, `date: ${this.formatDate(mem.created, 'long', true)}`, `score: ${mem.score.toFixed(3)}`, `::end:memory:${this.hash(mem)}`, ].join('\n'); }).join('\n') : 'no memory'; this.state('parse', `memory`); console.log('packet memory feecting resolve', memory); return this.question(`${this.askChr}feecting parse ${text}`); }).then(feecting => { data.feecting = feecting.a.data; this.state('resolve', `memory`); return resolve({ text: feecting.a.text, html: feecting.a.html, data, }) }).catch(err => { this.state('reject', `memory`) return this.error(packet, err, reject); }); }); }, /************** method: knowledge params: packet describe: Knowledge base wisdom ***************/ knowledge(packet) { this.context('knowledge', packet.q.text); this.action('method', `knowledge`); return new Promise((resolve, reject) => { if (!packet.q.text) return resolve(this._messages.notext); const {params} = packet.q.meta; const data = {}; if (params[1]) this.vars.knowledge.limit = params[1]; this.func.knowledge(packet.q).then(wisdom => { data.wisdom = wisdom; const text = wisdom.length ? wisdom.map(item => { return [ `::begin:knowledge:${item._id}`, `p: ${item.content}`, `created: ${this.lib.formatDate(item.created, 'long', true)}`, `score: ${item.score.toFixed(3)}`, `::end:knowledge:${this.lib.hash(item)}`, ].join('\n'); }).join('\n') : this.vars.messages.no_knowledge; this.state('parse', `knowledge`); return this.question(`${this.askChr}feecting parse ${text}`); }).then(feecting => { data.feecting = feecting.a.data; this.state('resolve', `knowledge`); return resolve({ text: feecting.a.text, html: feecting.a.html, data, }) }).catch(err => { this.state('reject', `knowledge`); return this.error(err, packet, reject); }); }); }, /************** method: know params: packet describe: add data to the knowledge base example: #data mem:[id] [content to store in memory] ***************/ know(packet) { this.context('know', packet.id); return new Promise((resolve, reject) => { if (!packet.q.text) return resolve(this._messages.notext); const {meta, text} = packet.q; const {collection} = this.vars.knowledge; const data = { id: packet.id, content: packet.q.text, }; let id = false, func = 'insert'; // if param[1] id is found then update record if (meta.params[1]) { id = meta.params[1]; func = 'update'; data.modified = Date.now(); } else { data.modified = null; data.created = Date.now(); } this.func[func]({id,collection,data}).then(ins => { this.state('resolve', 'add'); return resolve({ text: `id: ${ins.insertedId || id}`, html: `id: ${ins.insertedId || id}`, data: ins.insertedId, }); }).catch(err => { this.state('reject', 'add'); return this.error(err, packet, reject); }); }); }, /************** method: listidx params: packet describe: List Indexes ***************/ listidx(packet) { this.context('index', packet.q.text); this.action('method', 'index'); return new Promise((resolve, reject) => { this.func.indexes(packet.q).then(idx => { this.state('resolve', 'indexes'); return resolve({ text: 'indexes', html: 'indexes', data: idx }) }).reject(err => { return this.error(err, packet, reject); }) }); }, }, onInit(data, resolve) { const {personal} = this.license(); // get the license config const agent_license = this.info().VLA; // get agent license const license_check = this.license_check(personal, agent_license); // check license // return this.start if license_check passes otherwise stop. return license_check ? this.start(data, resolve) : this.stop(data, resolve); }, onReady(data, resolve) { const {VLA} = this.info(); const {mongo} = this.data().global; this.vars.database = mongo.database; this.modules.client = new MongoClient(mongo.uri); this.prompt(`${this.vars.messages.ready} > VLA:${VLA.uid}`); return resolve(data); }, onError(err, data, reject) { this.prompt(this.vars.messages.error); console.log(err); return reject ? reject(err) : false; }, }); export default DataDeva