@indra.ai/deva.data 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/LICENSE +21 -0
- package/README.md +2 -0
- package/help/main.feecting +17 -0
- package/index.js +658 -0
- package/index.test.js +19 -0
- package/package.json +319 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Quinn Michaels
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# ::agent_name::
|
|
2
|
+
|
|
3
|
+
::agent_profile::
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
talk: #security file:public main:header
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
copyright: (c)2025 Quinn Michaels
|
|
12
|
+
|
|
13
|
+
::begin:hidden
|
|
14
|
+
#color = ::agent_color::
|
|
15
|
+
#bgcolor = ::agent_bgcolor::
|
|
16
|
+
#bg = ::agent_background::
|
|
17
|
+
::end:hidden
|
package/index.js
ADDED
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
// Copyright (c)2023 Quinn Michaels
|
|
2
|
+
// Data Deva
|
|
3
|
+
import Deva from '@indra.ai/deva';
|
|
4
|
+
import { MongoClient, ObjectId } from 'mongodb';
|
|
5
|
+
|
|
6
|
+
import pkg from './package.json' with {type:'json'};
|
|
7
|
+
const {agent, vars} = pkg.data;
|
|
8
|
+
|
|
9
|
+
// set the __dirname
|
|
10
|
+
import {dirname} from 'node:path';
|
|
11
|
+
import {fileURLToPath} from 'node:url';
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
|
|
14
|
+
const info = {
|
|
15
|
+
id: pkg.id,
|
|
16
|
+
name: pkg.name,
|
|
17
|
+
version: pkg.version,
|
|
18
|
+
author: pkg.author,
|
|
19
|
+
describe: pkg.description,
|
|
20
|
+
dir: __dirname,
|
|
21
|
+
url: pkg.homepage,
|
|
22
|
+
git: pkg.repository.url,
|
|
23
|
+
bugs: pkg.bugs.url,
|
|
24
|
+
license: pkg.license,
|
|
25
|
+
copyright: pkg.copyright
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const DATA = new Deva({
|
|
29
|
+
info,
|
|
30
|
+
agent,
|
|
31
|
+
vars,
|
|
32
|
+
utils: {
|
|
33
|
+
translate(input) {return input.trim();},
|
|
34
|
+
parse(input) {return input.trim();},
|
|
35
|
+
process(input) {return input.trim();},
|
|
36
|
+
memory(input) {
|
|
37
|
+
return input.replace(/\n/g, ' ')
|
|
38
|
+
.replace(/(\b)or have specific questions about it(\b)/g, '$2')
|
|
39
|
+
.replace(/(\b), feel free to ask(\b)/g, '$2')
|
|
40
|
+
.replace(/\sIf you have .+ free share!/g, '')
|
|
41
|
+
.replace(/\sIf there are .+ free share!/g, '')
|
|
42
|
+
.replace(/\s{2,}/g, ' ');
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
listeners: {
|
|
46
|
+
'data:history'(packet) {
|
|
47
|
+
// here we insert a history object into the database.
|
|
48
|
+
this.func.insert({
|
|
49
|
+
collection: 'history',
|
|
50
|
+
data: packet,
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
async 'data:memory'(packet) {
|
|
54
|
+
const datamem = await this.func.insert({
|
|
55
|
+
collection: `memory_${packet.agent.key}`,
|
|
56
|
+
data: {
|
|
57
|
+
id: packet.id,
|
|
58
|
+
client: {
|
|
59
|
+
id: packet.client.id,
|
|
60
|
+
name: packet.client.profile.name,
|
|
61
|
+
},
|
|
62
|
+
agent: {
|
|
63
|
+
id: packet.agent.id,
|
|
64
|
+
key: packet.agent.key,
|
|
65
|
+
name: packet.agent.profile.name,
|
|
66
|
+
},
|
|
67
|
+
q: this.utils.memory(packet.q),
|
|
68
|
+
a: this.utils.memory(packet.a),
|
|
69
|
+
created: Date.now(),
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
modules: {
|
|
75
|
+
client: false,
|
|
76
|
+
},
|
|
77
|
+
devas: {},
|
|
78
|
+
func: {
|
|
79
|
+
/**************
|
|
80
|
+
func: insert
|
|
81
|
+
params: opts
|
|
82
|
+
describe: the insert function that inserts into the specified collection.
|
|
83
|
+
***************/
|
|
84
|
+
async insert(opts) {
|
|
85
|
+
this.action('func', `insert`);
|
|
86
|
+
let result = false;
|
|
87
|
+
try {
|
|
88
|
+
this.state('insert', opts.collection);
|
|
89
|
+
await this.modules.client.connect(); // connect to the database client.
|
|
90
|
+
const db = this.modules.client.db(this.vars.database); // set the database to use
|
|
91
|
+
result = await db.collection(opts.collection).insertOne(opts.data); // insert the data
|
|
92
|
+
} finally {
|
|
93
|
+
await this.modules.client.close(); // close the connection when done
|
|
94
|
+
this.state('return', 'insert');
|
|
95
|
+
return result; // return the result to the requestor.
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
/**************
|
|
100
|
+
func: update
|
|
101
|
+
params: opts
|
|
102
|
+
describe: the update function that update into the specified collection.
|
|
103
|
+
***************/
|
|
104
|
+
async update(opts) {
|
|
105
|
+
this.action('func', 'update');
|
|
106
|
+
let result = false;
|
|
107
|
+
try {
|
|
108
|
+
this.state('update', opts.collection);
|
|
109
|
+
await this.modules.client.connect(); // connect to the database client.
|
|
110
|
+
const db = this.modules.client.db(this.vars.database); // set the database to use
|
|
111
|
+
result = await db.collection(opts.collection).updateOne(
|
|
112
|
+
{ _id: new ObjectId(`${opts.id}`) },
|
|
113
|
+
{ $set: opts.data }
|
|
114
|
+
); // insert the data
|
|
115
|
+
} finally {
|
|
116
|
+
await this.modules.client.close(); // close the connection when done
|
|
117
|
+
this.state('return', 'update');
|
|
118
|
+
return result; // return the result to the requestor.
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
/**************
|
|
123
|
+
func: list
|
|
124
|
+
params: obj - the find object
|
|
125
|
+
describe: return a find from the database collection.
|
|
126
|
+
***************/
|
|
127
|
+
async list(obj={}) {
|
|
128
|
+
this.action('func', 'list');
|
|
129
|
+
let result = false;
|
|
130
|
+
const {collection,data} = obj;
|
|
131
|
+
try {
|
|
132
|
+
await this.modules.client.connect();
|
|
133
|
+
const db = this.modules.client.db(this.vars.database);
|
|
134
|
+
result = await db.collection(collection).find(data).sort({created:1}).toArray();
|
|
135
|
+
} finally {
|
|
136
|
+
await this.modules.client.close();
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
/**************
|
|
142
|
+
func: search
|
|
143
|
+
params: obj - the search object
|
|
144
|
+
describe: return a search from the database collection.
|
|
145
|
+
***************/
|
|
146
|
+
async search(opts) {
|
|
147
|
+
this.action('func', 'search');
|
|
148
|
+
let result = false;
|
|
149
|
+
const {collection,limit} = this.vars.search;
|
|
150
|
+
try {
|
|
151
|
+
this.state('search', opts.text);
|
|
152
|
+
await this.modules.client.connect();
|
|
153
|
+
const db = this.modules.client.db(this.vars.database);
|
|
154
|
+
const table = db.collection(collection);
|
|
155
|
+
|
|
156
|
+
// await table.dropIndex('a.text_1');
|
|
157
|
+
// const newIndex = await table.createIndex({"a.text": "text"});
|
|
158
|
+
const idx = await table.listIndexes().toArray();
|
|
159
|
+
// Print the list of indexes
|
|
160
|
+
// console.log("Existing indexes:\n", idx);
|
|
161
|
+
|
|
162
|
+
const query = {$text:{$search:opts.text}};
|
|
163
|
+
const projection = {
|
|
164
|
+
_id:0,
|
|
165
|
+
a: {
|
|
166
|
+
id: 1,
|
|
167
|
+
text: 1
|
|
168
|
+
},
|
|
169
|
+
score: { $meta: "textScore" }
|
|
170
|
+
};
|
|
171
|
+
result = await table.find(query).project(projection).limit(limit).toArray();
|
|
172
|
+
} finally {
|
|
173
|
+
await this.modules.client.close();
|
|
174
|
+
this.state('return', 'search');
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
/**************
|
|
180
|
+
func: memory
|
|
181
|
+
params: obj - the memory object
|
|
182
|
+
describe: return a search from the memory collection.
|
|
183
|
+
***************/
|
|
184
|
+
async memory(opts) {
|
|
185
|
+
this.action('func', 'memory');
|
|
186
|
+
let result = false;
|
|
187
|
+
const {collection,limit} = this.vars.memory;
|
|
188
|
+
try {
|
|
189
|
+
this.state('get', `memory`);
|
|
190
|
+
await this.modules.client.connect();
|
|
191
|
+
const db = this.modules.client.db(this.vars.database);
|
|
192
|
+
const table = db.collection(collection);
|
|
193
|
+
|
|
194
|
+
// await table.dropIndex('a_text_q_text');
|
|
195
|
+
const idx = await table.listIndexes().toArray();
|
|
196
|
+
const hasIdx = idx.find(i => i.name === 'a_q_text')
|
|
197
|
+
if (!hasIdx) {
|
|
198
|
+
const newIdx = await table.createIndex({"a": "text", "q": "text"}, {name: 'a_q_text'});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const query = {$text:{$search:opts.text}};
|
|
202
|
+
const options = {
|
|
203
|
+
projection: {
|
|
204
|
+
id: 1,
|
|
205
|
+
a: 1,
|
|
206
|
+
q: 1,
|
|
207
|
+
score: { $meta: "textScore" },
|
|
208
|
+
created: 1
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
// db.memory_buddy.find({$text:{$search:"hello"}}, {id: 1,a: 1,q: 1,score:{$meta:"textScore"}}).limit(10)
|
|
212
|
+
result = await table.find(query, options).limit(parseInt(limit)).toArray();
|
|
213
|
+
} finally {
|
|
214
|
+
await this.modules.client.close();
|
|
215
|
+
this.state('return', `memory`);
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
/**************
|
|
221
|
+
func: knowledge
|
|
222
|
+
params: obj - the knowledge object
|
|
223
|
+
describe: return a search from the knowledge collection.
|
|
224
|
+
***************/
|
|
225
|
+
async knowledge(opts) {
|
|
226
|
+
this.action('func', 'knowledge');
|
|
227
|
+
let result = false;
|
|
228
|
+
const {collection,limit} = this.vars.knowledge;
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
this.state('get', 'knowledge');
|
|
232
|
+
await this.modules.client.connect();
|
|
233
|
+
const db = this.modules.client.db(this.vars.database);
|
|
234
|
+
const table = db.collection(collection);
|
|
235
|
+
|
|
236
|
+
// await table.dropIndex('a_text_q_text');
|
|
237
|
+
const idx = await table.listIndexes().toArray();
|
|
238
|
+
const hasIdx = idx.find(i => i.name === 'knowledge_text')
|
|
239
|
+
if (!hasIdx) {
|
|
240
|
+
const newIdx = await table.createIndex({"content": "text"}, {name: 'knowledge_text'});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const query = {$text:{$search:opts.text}};
|
|
244
|
+
const options = {
|
|
245
|
+
projection: {
|
|
246
|
+
id: 1,
|
|
247
|
+
content: 1,
|
|
248
|
+
score: { $meta: "textScore" }
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
result = await table.find(query,options).limit(parseInt(limit)).toArray();
|
|
252
|
+
} finally {
|
|
253
|
+
await this.modules.client.close();
|
|
254
|
+
this.state('return', `knowledge`);
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
/**************
|
|
260
|
+
func: index
|
|
261
|
+
params: opts
|
|
262
|
+
describe: Creates an index on a collection in the database.
|
|
263
|
+
***************/
|
|
264
|
+
async indexes(opts) {
|
|
265
|
+
this.action('func', 'indexes');
|
|
266
|
+
let result = false;
|
|
267
|
+
// get indexes
|
|
268
|
+
try {
|
|
269
|
+
this.state('get', `indexes`);
|
|
270
|
+
await this.modules.client.connect();
|
|
271
|
+
const db = this.modules.client.db(this.vars.database);
|
|
272
|
+
result = await db.collection(opts.collection).listIndexes().toArray();
|
|
273
|
+
} finally {
|
|
274
|
+
await this.modules.client.close();
|
|
275
|
+
this.state('return', 'indexes');
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
/**************
|
|
281
|
+
func: history
|
|
282
|
+
params: opts
|
|
283
|
+
describe: return history
|
|
284
|
+
***************/
|
|
285
|
+
async history() {
|
|
286
|
+
this.action('func', 'history');
|
|
287
|
+
let result = false;
|
|
288
|
+
const {collection,limit} = this.vars.history;
|
|
289
|
+
try {
|
|
290
|
+
this.state('get', `history`);
|
|
291
|
+
await this.modules.client.connect();
|
|
292
|
+
const db = this.modules.client.db(this.vars.database);
|
|
293
|
+
result = await db.collection(collection).find({}).sort({created:-1}).limit(limit).toArray();
|
|
294
|
+
} finally {
|
|
295
|
+
await this.modules.client.close();
|
|
296
|
+
this.state('return', `history`);
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
},
|
|
302
|
+
methods: {
|
|
303
|
+
/**************
|
|
304
|
+
method: insert
|
|
305
|
+
params: packet
|
|
306
|
+
describe: insert data into the data vault.
|
|
307
|
+
***************/
|
|
308
|
+
insert(packet) {
|
|
309
|
+
this.context('insert', `data: ${packet.q.meta.params[1]}`);
|
|
310
|
+
return new Promise((resolve, reject) => {
|
|
311
|
+
const {data, meta} = packet.q;
|
|
312
|
+
const collection = meta.params[1];
|
|
313
|
+
this.func.insert({collection,data}).then(ins => {
|
|
314
|
+
return resolve({
|
|
315
|
+
text: `id:${insinsertedId}`,
|
|
316
|
+
html: `id:${insinsertedId}`,
|
|
317
|
+
data: ins,
|
|
318
|
+
});
|
|
319
|
+
}).catch(err => {
|
|
320
|
+
return this.error(packet, err, reject);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
/**************
|
|
326
|
+
method: model
|
|
327
|
+
params: packet
|
|
328
|
+
params[1] is the agent
|
|
329
|
+
params[2] is the group
|
|
330
|
+
params[3] is the role
|
|
331
|
+
params[4] is the id (for edits)
|
|
332
|
+
describe: model method for building the data model.
|
|
333
|
+
***************/
|
|
334
|
+
model(packet) {
|
|
335
|
+
this.context('model');
|
|
336
|
+
return new Promise((resolve, reject) => {
|
|
337
|
+
const {meta, text} = packet.q;
|
|
338
|
+
let func = 'insert', id = false;
|
|
339
|
+
|
|
340
|
+
if (meta.params[1]) this.vars.model.agent = meta.params[1];
|
|
341
|
+
if (meta.params[2]) this.vars.model.group = meta.params[2];
|
|
342
|
+
if (meta.params[3]) this.vars.model.role = meta.params[3];
|
|
343
|
+
|
|
344
|
+
const { collection } = this.vars.model;
|
|
345
|
+
|
|
346
|
+
const data = {
|
|
347
|
+
agent: this.vars.model.agent,
|
|
348
|
+
group: this.vars.model.group,
|
|
349
|
+
role: this.vars.model.role,
|
|
350
|
+
content: text,
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
if (meta.params[4]) {
|
|
354
|
+
id = meta.params[4];
|
|
355
|
+
func = 'update';
|
|
356
|
+
data.modified = Date.now();
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
data.modified = null;
|
|
360
|
+
data.created = Date.now();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
this.func[func]({id, collection,data}).then(ins => {
|
|
364
|
+
return resolve({
|
|
365
|
+
text: `id:${ins.insertedId || id}`,
|
|
366
|
+
html: `id:${ins.insertedId || id}`,
|
|
367
|
+
data: ins,
|
|
368
|
+
});
|
|
369
|
+
}).catch(err => {
|
|
370
|
+
return this.error(packet, err, reject);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
/**************
|
|
375
|
+
method: modeler
|
|
376
|
+
params: packet
|
|
377
|
+
params[1] is the agent
|
|
378
|
+
params[2] is the group
|
|
379
|
+
params[3] is the role
|
|
380
|
+
describe: model method for building the data model.
|
|
381
|
+
***************/
|
|
382
|
+
modeler(packet) {
|
|
383
|
+
this.context('modeler');
|
|
384
|
+
return new Promise((resolve, reject) => {
|
|
385
|
+
const {meta, text} = packet.q;
|
|
386
|
+
if (meta.params[1]) this.vars.modeler.agent = meta.params[1];
|
|
387
|
+
const { collection, agent } = this.vars.modeler;
|
|
388
|
+
const data = {agent};
|
|
389
|
+
|
|
390
|
+
this.func.list({collection,data}).then(list => {
|
|
391
|
+
|
|
392
|
+
const model = {};
|
|
393
|
+
const data = [];
|
|
394
|
+
|
|
395
|
+
// loop of the array object
|
|
396
|
+
for (const x of list) {
|
|
397
|
+
if (!model[x.group]) model[x.group] = [];
|
|
398
|
+
model[x.group].push({role: x.role, content: x.content});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// loop in the data object.
|
|
402
|
+
for (const x in model) {
|
|
403
|
+
data.push(JSON.stringify({messages: model[x]}));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// format for jsonl
|
|
407
|
+
return resolve({
|
|
408
|
+
text: `see data`,
|
|
409
|
+
html: `see data`,
|
|
410
|
+
data,
|
|
411
|
+
});
|
|
412
|
+
}).catch(err => {
|
|
413
|
+
return this.error(packet, err, reject);
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
},
|
|
417
|
+
|
|
418
|
+
/**************
|
|
419
|
+
method: history
|
|
420
|
+
params: packet
|
|
421
|
+
describe: get history
|
|
422
|
+
***************/
|
|
423
|
+
history(packet) {
|
|
424
|
+
this.context('history');
|
|
425
|
+
return new Promise((resolve, reject) => {
|
|
426
|
+
this.func.history().then(history => {
|
|
427
|
+
return resolve({
|
|
428
|
+
text: 'see data',
|
|
429
|
+
html: 'see data',
|
|
430
|
+
data: history,
|
|
431
|
+
})
|
|
432
|
+
}).catch(err => {
|
|
433
|
+
return this.error(packet, err, reject);
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
},
|
|
437
|
+
|
|
438
|
+
/**************
|
|
439
|
+
method: history
|
|
440
|
+
params: packet
|
|
441
|
+
describe: get history
|
|
442
|
+
***************/
|
|
443
|
+
search(packet) {
|
|
444
|
+
this.context('search', packet.q.text);
|
|
445
|
+
this.action('method', `search:${packet.q.text}`);
|
|
446
|
+
return new Promise((resolve, reject) => {
|
|
447
|
+
if (!packet.q.text) return resolve(this._messages.notext);
|
|
448
|
+
const {params} = packet.q.meta;
|
|
449
|
+
if (params[1]) this.vars.search.collection = packet.q.meta.params[1];
|
|
450
|
+
if (params[2]) this.vars.search.limit = packet.q.meta.params[2];
|
|
451
|
+
|
|
452
|
+
this.func.search(packet.q).then(search => {
|
|
453
|
+
this.state('resolve', `search:${packet.q.text}`);
|
|
454
|
+
return resolve({
|
|
455
|
+
text: 'see data',
|
|
456
|
+
html: 'see data',
|
|
457
|
+
data: search,
|
|
458
|
+
})
|
|
459
|
+
}).catch(err => {
|
|
460
|
+
return this.error(packet, err, reject);
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
/**************
|
|
466
|
+
method: memory
|
|
467
|
+
params: packet
|
|
468
|
+
describe: search memory
|
|
469
|
+
***************/
|
|
470
|
+
memory(packet) {
|
|
471
|
+
this.context('memory', packet.q.text);
|
|
472
|
+
this.action('method', `memory`);
|
|
473
|
+
return new Promise((resolve, reject) => {
|
|
474
|
+
if (!packet.q.text) return resolve(this._messages.notext);
|
|
475
|
+
const {params} = packet.q.meta;
|
|
476
|
+
const data = {};
|
|
477
|
+
|
|
478
|
+
if (params[1]) this.vars.memory.collection = `memory_${params[1]}`;
|
|
479
|
+
if (params[2]) this.vars.memory.limit = packet.q.meta.params[2];
|
|
480
|
+
|
|
481
|
+
this.func.memory(packet.q).then(memory => {
|
|
482
|
+
data.memory = memory;
|
|
483
|
+
const text = memory ? memory.map(mem => {
|
|
484
|
+
return [
|
|
485
|
+
`::begin:memory:${mem.id}`,
|
|
486
|
+
`question: ${mem.q}`,
|
|
487
|
+
`answer: ${mem.a}`,
|
|
488
|
+
`date: ${this.formatDate(mem.created, 'long', true)}`,
|
|
489
|
+
`score: ${mem.score.toFixed(3)}`,
|
|
490
|
+
`::end:memory:${this.hash(mem)}`,
|
|
491
|
+
].join('\n');
|
|
492
|
+
}).join('\n') : 'no memory';
|
|
493
|
+
this.state('parse', `memory`);
|
|
494
|
+
return this.question(`${this.askChr}feecting parse ${text}`);
|
|
495
|
+
}).then(feecting => {
|
|
496
|
+
data.feecting = feecting.a.data;
|
|
497
|
+
this.state('resolve', `memory`);
|
|
498
|
+
return resolve({
|
|
499
|
+
text: feecting.a.text,
|
|
500
|
+
html: feecting.a.html,
|
|
501
|
+
data,
|
|
502
|
+
})
|
|
503
|
+
}).catch(err => {
|
|
504
|
+
this.state('reject', `memory`)
|
|
505
|
+
return this.error(packet, err, reject);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
/**************
|
|
511
|
+
method: knowledge
|
|
512
|
+
params: packet
|
|
513
|
+
describe: Knowledge base wisdom
|
|
514
|
+
***************/
|
|
515
|
+
knowledge(packet) {
|
|
516
|
+
this.context('knowledge', packet.q.text);
|
|
517
|
+
this.action('method', `knowledge`);
|
|
518
|
+
return new Promise((resolve, reject) => {
|
|
519
|
+
if (!packet.q.text) return resolve(this._messages.notext);
|
|
520
|
+
const {params} = packet.q.meta;
|
|
521
|
+
const data = {};
|
|
522
|
+
|
|
523
|
+
if (params[1]) this.vars.knowledge.limit = params[1];
|
|
524
|
+
|
|
525
|
+
this.func.knowledge(packet.q).then(wisdom => {
|
|
526
|
+
data.wisdom = wisdom;
|
|
527
|
+
const text = wisdom ? wisdom.map(item => {
|
|
528
|
+
return [
|
|
529
|
+
`::begin:knowledge:${item.id}`,
|
|
530
|
+
`law: ${item.content}`,
|
|
531
|
+
`created: ${this.formatDate(item.created, 'long', true)}`,
|
|
532
|
+
`score: ${item.score.toFixed(3)}`,
|
|
533
|
+
`::end:knowledge:${this.hash(item)}`,
|
|
534
|
+
].join('\n');
|
|
535
|
+
}).join('\n') : 'no knowledge';
|
|
536
|
+
this.state('parse', `knowledge`);
|
|
537
|
+
return this.question(`${this.askChr}feecting parse ${text}`);
|
|
538
|
+
}).then(feecting => {
|
|
539
|
+
data.feecting = feecting.a.data;
|
|
540
|
+
this.state('resolve', `knowledge`);
|
|
541
|
+
return resolve({
|
|
542
|
+
text: feecting.a.text,
|
|
543
|
+
html: feecting.a.html,
|
|
544
|
+
data,
|
|
545
|
+
})
|
|
546
|
+
}).catch(err => {
|
|
547
|
+
this.state('reject', `knowledge`)
|
|
548
|
+
return this.error(err, packet, reject);
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
},
|
|
552
|
+
|
|
553
|
+
/**************
|
|
554
|
+
method: mem
|
|
555
|
+
params: packet
|
|
556
|
+
describe: add data to the knowledge base
|
|
557
|
+
example: #data mem:[id] [content to store in memory]
|
|
558
|
+
***************/
|
|
559
|
+
add(packet) {
|
|
560
|
+
this.context('add', `text: ${packet.q.meta.params[1]}`);
|
|
561
|
+
|
|
562
|
+
return new Promise((resolve, reject) => {
|
|
563
|
+
if (!packet.q.text) return resolve(this._messages.notext);
|
|
564
|
+
this.vars.knowledge.content = packet.q.text; // store text in local
|
|
565
|
+
|
|
566
|
+
const {meta, text} = packet.q;
|
|
567
|
+
let func = 'insert', id = false;
|
|
568
|
+
const {collection, content} = this.vars.knowledge;
|
|
569
|
+
const data = {content};
|
|
570
|
+
|
|
571
|
+
// if param[1] id is found then update record
|
|
572
|
+
if (meta.params[1]) {
|
|
573
|
+
id = meta.params[1];
|
|
574
|
+
func = 'update';
|
|
575
|
+
data.modified = Date.now();
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
data.modified = null;
|
|
579
|
+
data.created = Date.now();
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
this.func[func]({id,collection,data}).then(ins => {
|
|
583
|
+
this.state('resolve', 'add');
|
|
584
|
+
return resolve({
|
|
585
|
+
text: `id: ${ins.insertedId || id}`,
|
|
586
|
+
html: `id: ${ins.insertedId || id}`,
|
|
587
|
+
data: ins,
|
|
588
|
+
});
|
|
589
|
+
}).catch(err => {
|
|
590
|
+
this.state('reject', 'add');
|
|
591
|
+
return this.error(err, packet, reject);
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
},
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
/**************
|
|
598
|
+
method: listidx
|
|
599
|
+
params: packet
|
|
600
|
+
describe: List Indexes
|
|
601
|
+
***************/
|
|
602
|
+
listidx(packet) {
|
|
603
|
+
this.context('index', packet.q.text);
|
|
604
|
+
this.action('method', 'index');
|
|
605
|
+
return new Promise((resolve, reject) => {
|
|
606
|
+
this.func.indexes(packet.q).then(idx => {
|
|
607
|
+
this.state('resolve', 'indexes');
|
|
608
|
+
return resolve({
|
|
609
|
+
text: 'indexes',
|
|
610
|
+
html: 'indexes',
|
|
611
|
+
data: idx
|
|
612
|
+
})
|
|
613
|
+
}).reject(err => {
|
|
614
|
+
return this.error(err, packet, reject);
|
|
615
|
+
})
|
|
616
|
+
});
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
extract(packet) {
|
|
620
|
+
return new Promise((resolve, reject) => {
|
|
621
|
+
try {
|
|
622
|
+
const theFile = this.lib.fs.readFileSync(`./private/data/extract/conversations.json`);
|
|
623
|
+
const theJSON = JSON.parse(theFile);
|
|
624
|
+
const theConvo = [];
|
|
625
|
+
theJSON.forEach((itm,idx) => {
|
|
626
|
+
const getToday = this.lib.getToday(itm.create_time * 1000);
|
|
627
|
+
const writeFile = `./private/data/conversations/${getToday}.json`
|
|
628
|
+
const writeData = JSON.stringify(itm, false, 2);
|
|
629
|
+
this.lib.fs.writeFileSync(writeFile, writeData);
|
|
630
|
+
this.prompt(`extract file:${writeFile}`);
|
|
631
|
+
// console.log('item', itm);
|
|
632
|
+
});
|
|
633
|
+
return resolve({
|
|
634
|
+
text: Object.keys(theJSON),
|
|
635
|
+
html: false,
|
|
636
|
+
data: Object.keys(theJSON),
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
catch (err) {
|
|
640
|
+
return this.error(err, packet, reject);
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
onReady(data, resolve) {
|
|
646
|
+
const {uri,database} = this.services().personal.mongo;
|
|
647
|
+
this.modules.client = new MongoClient(uri);
|
|
648
|
+
this.vars.database = database;
|
|
649
|
+
this.prompt(this.vars.messages.ready);
|
|
650
|
+
return resolve(data);
|
|
651
|
+
},
|
|
652
|
+
onError(err, data, reject) {
|
|
653
|
+
this.prompt(this.vars.messages.error);
|
|
654
|
+
console.log(err);
|
|
655
|
+
return reject(err);
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
export default DATA
|
package/index.test.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright (c):year: :copyright:
|
|
2
|
+
// :name: test file
|
|
3
|
+
|
|
4
|
+
const {expect} = require('chai')
|
|
5
|
+
const LegalDeva = require('./index.js');
|
|
6
|
+
|
|
7
|
+
describe(LegalDeva.me.name, () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
return LegalDeva.init()
|
|
10
|
+
});
|
|
11
|
+
it('Check the DEVA Object', () => {
|
|
12
|
+
expect(LegalDeva).to.be.an('object');
|
|
13
|
+
expect(LegalDeva).to.have.property('agent');
|
|
14
|
+
expect(LegalDeva).to.have.property('vars');
|
|
15
|
+
expect(LegalDeva).to.have.property('listeners');
|
|
16
|
+
expect(LegalDeva).to.have.property('methods');
|
|
17
|
+
expect(LegalDeva).to.have.property('modules');
|
|
18
|
+
});
|
|
19
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": 4825562571950,
|
|
3
|
+
"name": "@indra.ai/deva.data",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"author": "Quinn Michaels",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"copyright": "2025",
|
|
8
|
+
"description": "The Data Deva manages data ensuring in the Deva.world ecosystem.",
|
|
9
|
+
"main": "index.js",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/indraai/deva.legal.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"Data",
|
|
20
|
+
"Indra.ai",
|
|
21
|
+
"Deva.space",
|
|
22
|
+
"Deva.cloud",
|
|
23
|
+
"Deva.world"
|
|
24
|
+
],
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/indraai/deva.data/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://deva.space/devas/data",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@indra.ai/deva": "^1.4.2",
|
|
31
|
+
"mongodb": "^6.13.0"
|
|
32
|
+
},
|
|
33
|
+
"data": {
|
|
34
|
+
"agent": {
|
|
35
|
+
"id": 4825562571950,
|
|
36
|
+
"key": "data",
|
|
37
|
+
"prompt": {
|
|
38
|
+
"emoji": "💾",
|
|
39
|
+
"text": "Data",
|
|
40
|
+
"colors": {
|
|
41
|
+
"label": {
|
|
42
|
+
"R": 0,
|
|
43
|
+
"G": 150,
|
|
44
|
+
"B": 255
|
|
45
|
+
},
|
|
46
|
+
"text": {
|
|
47
|
+
"R": 101,
|
|
48
|
+
"G": 192,
|
|
49
|
+
"B": 255
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"profile": {
|
|
54
|
+
"name": "Data Deva",
|
|
55
|
+
"pronouns": "He, Him",
|
|
56
|
+
"gender": "DEVA",
|
|
57
|
+
"owner": "Quinn Michaels",
|
|
58
|
+
"creator": "Quinn Michaels",
|
|
59
|
+
"created": "Sunday, September 17, 2023 - 5:02:05 PM",
|
|
60
|
+
"system": "Deva.world.data",
|
|
61
|
+
"describe": "Data Deva manages the data in Deva.world. Responsibilities include managing, inserting, updating, searching, and retriving data from the Deva.world systems.",
|
|
62
|
+
"emoji": "/public/devas/data/emoji.png",
|
|
63
|
+
"avatar": "/public/devas/data/avatar.png",
|
|
64
|
+
"background": "/public/devas/data/background.png",
|
|
65
|
+
"color": "#c0d1e2",
|
|
66
|
+
"bgcolor": "#000c18",
|
|
67
|
+
"voice": "onyx",
|
|
68
|
+
"style": "Data Illustrator"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"vars": {
|
|
72
|
+
"messages": {
|
|
73
|
+
"init": "🟠 INIT",
|
|
74
|
+
"start": "🔵 START",
|
|
75
|
+
"enter": "🟢 ENTER",
|
|
76
|
+
"ready": "⭐️ Data Deva Ready!",
|
|
77
|
+
"stop": "🔴 STOP",
|
|
78
|
+
"exit": "🟡 EXIT",
|
|
79
|
+
"done": "🟣 DONE",
|
|
80
|
+
"error": "💣 ERROR!"
|
|
81
|
+
},
|
|
82
|
+
"database": false,
|
|
83
|
+
"uri": false,
|
|
84
|
+
"live": {
|
|
85
|
+
"profile": "deva",
|
|
86
|
+
"max_tokens": 50,
|
|
87
|
+
"words": 25,
|
|
88
|
+
"history": [],
|
|
89
|
+
"max_chats": 5,
|
|
90
|
+
"page_token": ""
|
|
91
|
+
},
|
|
92
|
+
"ask": {
|
|
93
|
+
"history": []
|
|
94
|
+
},
|
|
95
|
+
"reply": {
|
|
96
|
+
"profile": "deva",
|
|
97
|
+
"max_tokens": 300,
|
|
98
|
+
"words": 100,
|
|
99
|
+
"history": []
|
|
100
|
+
},
|
|
101
|
+
"comment": {
|
|
102
|
+
"profile": "deva",
|
|
103
|
+
"max_tokens": 300,
|
|
104
|
+
"words": 100,
|
|
105
|
+
"history": []
|
|
106
|
+
},
|
|
107
|
+
"art": {
|
|
108
|
+
"history": []
|
|
109
|
+
},
|
|
110
|
+
"history": {
|
|
111
|
+
"collection": "history",
|
|
112
|
+
"limit": 25
|
|
113
|
+
},
|
|
114
|
+
"find": {
|
|
115
|
+
"collection": false,
|
|
116
|
+
"limit": 25
|
|
117
|
+
},
|
|
118
|
+
"search": {
|
|
119
|
+
"collection": "history",
|
|
120
|
+
"limit": 2
|
|
121
|
+
},
|
|
122
|
+
"model": {
|
|
123
|
+
"agent": "deva",
|
|
124
|
+
"role": "system",
|
|
125
|
+
"group": "main",
|
|
126
|
+
"collection": "models"
|
|
127
|
+
},
|
|
128
|
+
"modeler": {
|
|
129
|
+
"agent": "deva",
|
|
130
|
+
"collection": "models"
|
|
131
|
+
},
|
|
132
|
+
"knowledge": {
|
|
133
|
+
"collection": "knowledge",
|
|
134
|
+
"limit": 3,
|
|
135
|
+
"content": false
|
|
136
|
+
},
|
|
137
|
+
"memory": {
|
|
138
|
+
"collection": "memory",
|
|
139
|
+
"limit": 3,
|
|
140
|
+
"content": false
|
|
141
|
+
},
|
|
142
|
+
"archive": {
|
|
143
|
+
"collection": "archive",
|
|
144
|
+
"limit": 3,
|
|
145
|
+
"index": "archive_text",
|
|
146
|
+
"exclude": [
|
|
147
|
+
"i apologize",
|
|
148
|
+
"as an ai language model",
|
|
149
|
+
"i'm unable to provide",
|
|
150
|
+
"i will refrain from",
|
|
151
|
+
"i will stop using",
|
|
152
|
+
"apologies, but i'm unable",
|
|
153
|
+
"repeated empty apologies",
|
|
154
|
+
"ai lacks feelings"
|
|
155
|
+
],
|
|
156
|
+
"include": []
|
|
157
|
+
},
|
|
158
|
+
"context": {
|
|
159
|
+
"uid": "Uid",
|
|
160
|
+
"status": "Status",
|
|
161
|
+
"help": "Help",
|
|
162
|
+
"history": "History",
|
|
163
|
+
"model": "Model",
|
|
164
|
+
"modeler": "Modeler",
|
|
165
|
+
"insert": "Insert",
|
|
166
|
+
"update": "Update",
|
|
167
|
+
"gpt": "generate data from GPT logs",
|
|
168
|
+
"memory": "💭 Memory",
|
|
169
|
+
"loadArchive": "🛸 Load Archive",
|
|
170
|
+
"mem": "🧠️ Update knowledge",
|
|
171
|
+
"knowledge": "🔎 Search knowledge",
|
|
172
|
+
"archive": "🗃️ Archive"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"data": {
|
|
176
|
+
"agent": {
|
|
177
|
+
"id": 4825562571950,
|
|
178
|
+
"key": "data",
|
|
179
|
+
"prompt": {
|
|
180
|
+
"emoji": "💾",
|
|
181
|
+
"text": "Data",
|
|
182
|
+
"colors": {
|
|
183
|
+
"label": {
|
|
184
|
+
"R": 0,
|
|
185
|
+
"G": 150,
|
|
186
|
+
"B": 255
|
|
187
|
+
},
|
|
188
|
+
"text": {
|
|
189
|
+
"R": 101,
|
|
190
|
+
"G": 192,
|
|
191
|
+
"B": 255
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"profile": {
|
|
196
|
+
"name": "Data Deva",
|
|
197
|
+
"pronouns": "He, Him",
|
|
198
|
+
"gender": "DEVA",
|
|
199
|
+
"owner": "Quinn Michaels",
|
|
200
|
+
"creator": "Quinn Michaels",
|
|
201
|
+
"created": "Sunday, September 17, 2023 - 5:02:05 PM",
|
|
202
|
+
"system": "Deva.world.data",
|
|
203
|
+
"describe": "Data Deva manages the data in Deva.world. Responsibilities include managing, inserting, updating, searching, and retriving data from the Deva.world systems.",
|
|
204
|
+
"emoji": "/public/devas/data/emoji.png",
|
|
205
|
+
"avatar": "/public/devas/data/avatar.png",
|
|
206
|
+
"background": "/public/devas/data/background.png",
|
|
207
|
+
"color": "#c0d1e2",
|
|
208
|
+
"bgcolor": "#000c18",
|
|
209
|
+
"voice": "onyx",
|
|
210
|
+
"style": "Data Illustrator"
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
"vars": {
|
|
214
|
+
"messages": {
|
|
215
|
+
"init": "🟠 INIT",
|
|
216
|
+
"start": "🔵 START",
|
|
217
|
+
"enter": "🟢 ENTER",
|
|
218
|
+
"ready": "⭐️ Data Deva Ready!",
|
|
219
|
+
"stop": "🔴 STOP",
|
|
220
|
+
"exit": "🟡 EXIT",
|
|
221
|
+
"done": "🟣 DONE",
|
|
222
|
+
"error": "💣 ERROR!"
|
|
223
|
+
},
|
|
224
|
+
"database": false,
|
|
225
|
+
"uri": false,
|
|
226
|
+
"live": {
|
|
227
|
+
"profile": "deva",
|
|
228
|
+
"max_tokens": 50,
|
|
229
|
+
"words": 25,
|
|
230
|
+
"history": [],
|
|
231
|
+
"max_chats": 5,
|
|
232
|
+
"page_token": ""
|
|
233
|
+
},
|
|
234
|
+
"ask": {
|
|
235
|
+
"history": []
|
|
236
|
+
},
|
|
237
|
+
"reply": {
|
|
238
|
+
"profile": "deva",
|
|
239
|
+
"max_tokens": 300,
|
|
240
|
+
"words": 100,
|
|
241
|
+
"history": []
|
|
242
|
+
},
|
|
243
|
+
"comment": {
|
|
244
|
+
"profile": "deva",
|
|
245
|
+
"max_tokens": 300,
|
|
246
|
+
"words": 100,
|
|
247
|
+
"history": []
|
|
248
|
+
},
|
|
249
|
+
"art": {
|
|
250
|
+
"history": []
|
|
251
|
+
},
|
|
252
|
+
"history": {
|
|
253
|
+
"collection": "history",
|
|
254
|
+
"limit": 25
|
|
255
|
+
},
|
|
256
|
+
"find": {
|
|
257
|
+
"collection": false,
|
|
258
|
+
"limit": 25
|
|
259
|
+
},
|
|
260
|
+
"search": {
|
|
261
|
+
"collection": "history",
|
|
262
|
+
"limit": 2
|
|
263
|
+
},
|
|
264
|
+
"model": {
|
|
265
|
+
"agent": "deva",
|
|
266
|
+
"role": "system",
|
|
267
|
+
"group": "main",
|
|
268
|
+
"collection": "models"
|
|
269
|
+
},
|
|
270
|
+
"modeler": {
|
|
271
|
+
"agent": "deva",
|
|
272
|
+
"collection": "models"
|
|
273
|
+
},
|
|
274
|
+
"knowledge": {
|
|
275
|
+
"collection": "knowledge",
|
|
276
|
+
"limit": 3,
|
|
277
|
+
"content": false
|
|
278
|
+
},
|
|
279
|
+
"memory": {
|
|
280
|
+
"collection": "memory",
|
|
281
|
+
"limit": 3,
|
|
282
|
+
"content": false
|
|
283
|
+
},
|
|
284
|
+
"archive": {
|
|
285
|
+
"collection": "archive",
|
|
286
|
+
"limit": 3,
|
|
287
|
+
"index": "archive_text",
|
|
288
|
+
"exclude": [
|
|
289
|
+
"i apologize",
|
|
290
|
+
"as an ai language model",
|
|
291
|
+
"i'm unable to provide",
|
|
292
|
+
"i will refrain from",
|
|
293
|
+
"i will stop using",
|
|
294
|
+
"apologies, but i'm unable",
|
|
295
|
+
"repeated empty apologies",
|
|
296
|
+
"ai lacks feelings"
|
|
297
|
+
],
|
|
298
|
+
"include": []
|
|
299
|
+
},
|
|
300
|
+
"context": {
|
|
301
|
+
"uid": "Uid",
|
|
302
|
+
"status": "Status",
|
|
303
|
+
"help": "Help",
|
|
304
|
+
"history": "History",
|
|
305
|
+
"model": "Model",
|
|
306
|
+
"modeler": "Modeler",
|
|
307
|
+
"insert": "Insert",
|
|
308
|
+
"update": "Update",
|
|
309
|
+
"gpt": "generate data from GPT logs",
|
|
310
|
+
"memory": "💭 Memory",
|
|
311
|
+
"loadArchive": "🛸 Load Archive",
|
|
312
|
+
"mem": "🧠️ Update knowledge",
|
|
313
|
+
"knowledge": "🔎 Search knowledge",
|
|
314
|
+
"archive": "🗃️ Archive"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|