@props-labs/mesh-os 0.1.8 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -9
- package/dist/core/client.d.ts +6 -3
- package/dist/core/client.js +193 -60
- package/dist/core/taxonomy.d.ts +12 -1
- package/dist/core/taxonomy.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -2
- package/package.json +1 -1
- package/src/templates/hasura/metadata/databases/default/tables/public_memories.yaml +6 -0
- package/src/templates/hasura/migrations/default/1_init/down.sql +17 -4
- package/src/templates/hasura/migrations/default/2_metadata_filtering/down.sql +4 -0
- package/src/templates/hasura/migrations/default/2_metadata_filtering/up.sql +44 -0
- package/src/templates/hasura/migrations/default/3_memory_expiry/down.sql +55 -0
- package/src/templates/hasura/migrations/default/3_memory_expiry/up.sql +108 -0
package/README.md
CHANGED
@@ -143,15 +143,8 @@ flowchart LR
|
|
143
143
|
|
144
144
|
## Getting Started
|
145
145
|
|
146
|
-
|
147
|
-
```bash
|
148
|
-
# Install the CLI tool
|
149
|
-
npm install -g @props-labs/mesh-os
|
146
|
+
> **Important Note**: The JavaScript client can only connect to an existing MeshOS instance. To launch a new MeshOS system, please use the [Python version](https://github.com/Props-Labs/mesh-os) which includes deployment capabilities.
|
150
147
|
|
151
|
-
# Create and start a new project
|
152
|
-
mesh-os init my-project && cd my-project
|
153
|
-
mesh-os up
|
154
|
-
```
|
155
148
|
|
156
149
|
## Usage
|
157
150
|
```typescript
|
@@ -161,7 +154,7 @@ import dotenv from 'dotenv';
|
|
161
154
|
// Load environment variables
|
162
155
|
dotenv.config();
|
163
156
|
|
164
|
-
//
|
157
|
+
// Connect To MeshOS
|
165
158
|
const client = new MeshOS({
|
166
159
|
url: process.env.HASURA_URL || 'http://localhost:8080',
|
167
160
|
apiKey: process.env.HASURA_ADMIN_SECRET || 'meshos',
|
package/dist/core/client.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { EdgeType, type AgentStatus, type EdgeMetadata, type MemoryMetadata } from './taxonomy';
|
1
|
+
import { EdgeType, type AgentStatus, type EdgeMetadata, type MemoryMetadata, type TimestampFilter } from './taxonomy';
|
2
2
|
/**
|
3
3
|
* An agent in the system.
|
4
4
|
*/
|
@@ -21,6 +21,7 @@ export interface Memory {
|
|
21
21
|
embedding: number[];
|
22
22
|
createdAt: string;
|
23
23
|
updatedAt: string;
|
24
|
+
expiresAt?: string;
|
24
25
|
similarity?: number;
|
25
26
|
}
|
26
27
|
/**
|
@@ -91,7 +92,7 @@ export declare class MeshOS {
|
|
91
92
|
/**
|
92
93
|
* Store a new memory.
|
93
94
|
*/
|
94
|
-
remember(content: string, agentId: string, metadata?: Partial<MemoryMetadata
|
95
|
+
remember(content: string, agentId: string, metadata?: Partial<MemoryMetadata>, expiresAt?: string): Promise<Memory | Memory[]>;
|
95
96
|
/**
|
96
97
|
* Delete a specific memory.
|
97
98
|
*/
|
@@ -107,7 +108,7 @@ export declare class MeshOS {
|
|
107
108
|
/**
|
108
109
|
* Update a memory and optionally create a version edge to the previous version.
|
109
110
|
*/
|
110
|
-
updateMemory(memoryId: string, content: string, metadata?: Partial<MemoryMetadata>, createVersionEdge?: boolean): Promise<Memory>;
|
111
|
+
updateMemory(memoryId: string, content: string, metadata?: Partial<MemoryMetadata>, createVersionEdge?: boolean): Promise<Memory | Memory[]>;
|
111
112
|
/**
|
112
113
|
* Get memories connected to the given memory.
|
113
114
|
*/
|
@@ -134,6 +135,8 @@ export declare class MeshOS {
|
|
134
135
|
adaptiveThreshold?: boolean;
|
135
136
|
useSemanticExpansion?: boolean;
|
136
137
|
filters?: Record<string, unknown>;
|
138
|
+
createdAtFilter?: TimestampFilter;
|
139
|
+
expiresAtFilter?: TimestampFilter;
|
137
140
|
}): Promise<Memory[]>;
|
138
141
|
/**
|
139
142
|
* Internal method to perform recall with a specific threshold.
|
package/dist/core/client.js
CHANGED
@@ -12,7 +12,6 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
12
12
|
const boxen_1 = __importDefault(require("boxen"));
|
13
13
|
const taxonomy_1 = require("./taxonomy");
|
14
14
|
// Constants
|
15
|
-
const MIN_THRESHOLD = 0.3;
|
16
15
|
const SLUG_PATTERN = /^[a-z][a-z0-9_-]*[a-z0-9]$/;
|
17
16
|
/**
|
18
17
|
* GraphQL error class.
|
@@ -200,7 +199,7 @@ class MeshOS {
|
|
200
199
|
/**
|
201
200
|
* Store a new memory.
|
202
201
|
*/
|
203
|
-
async remember(content, agentId, metadata) {
|
202
|
+
async remember(content, agentId, metadata, expiresAt) {
|
204
203
|
// Create default metadata if none provided
|
205
204
|
const fullMetadata = taxonomy_1.memoryMetadataSchema.parse({
|
206
205
|
type: taxonomy_1.DataType.KNOWLEDGE,
|
@@ -211,41 +210,128 @@ class MeshOS {
|
|
211
210
|
additional: {},
|
212
211
|
...metadata
|
213
212
|
});
|
214
|
-
//
|
215
|
-
const
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
213
|
+
// Check if content needs chunking (8192 tokens is approximately 32K characters)
|
214
|
+
const CHUNK_SIZE = 32000;
|
215
|
+
if (content.length <= CHUNK_SIZE) {
|
216
|
+
// Create embedding for single chunk
|
217
|
+
const embedding = await this.createEmbedding(content);
|
218
|
+
const embeddingStr = `[${embedding.join(',')}]`;
|
219
|
+
const query = `
|
220
|
+
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector!, $expiresAt: timestamptz) {
|
221
|
+
insert_memories_one(object: {
|
222
|
+
content: $content,
|
223
|
+
agent_id: $agentId,
|
224
|
+
metadata: $metadata,
|
225
|
+
embedding: $embedding,
|
226
|
+
expires_at: $expiresAt
|
227
|
+
}) {
|
228
|
+
id
|
229
|
+
agent_id
|
230
|
+
content
|
231
|
+
metadata
|
232
|
+
embedding
|
233
|
+
created_at
|
234
|
+
updated_at
|
235
|
+
expires_at
|
236
|
+
}
|
232
237
|
}
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
238
|
+
`;
|
239
|
+
const result = await this.executeQuery(query, {
|
240
|
+
content,
|
241
|
+
agentId,
|
242
|
+
metadata: fullMetadata,
|
243
|
+
embedding: embeddingStr,
|
244
|
+
expiresAt
|
245
|
+
});
|
246
|
+
// Convert snake_case to camelCase
|
247
|
+
const { agent_id, created_at, updated_at, expires_at, ...rest } = result.insert_memories_one;
|
248
|
+
return {
|
249
|
+
...rest,
|
250
|
+
agentId: agent_id,
|
251
|
+
createdAt: created_at,
|
252
|
+
updatedAt: updated_at,
|
253
|
+
expiresAt: expires_at,
|
254
|
+
};
|
255
|
+
}
|
256
|
+
// Split content into chunks
|
257
|
+
const chunks = [];
|
258
|
+
for (let i = 0; i < content.length; i += CHUNK_SIZE) {
|
259
|
+
chunks.push(content.slice(i, i + CHUNK_SIZE));
|
260
|
+
}
|
261
|
+
// Store each chunk and create links
|
262
|
+
const memories = [];
|
263
|
+
let previousChunkId = null;
|
264
|
+
for (let i = 0; i < chunks.length; i++) {
|
265
|
+
const chunkMetadata = {
|
266
|
+
...fullMetadata,
|
267
|
+
additional: {
|
268
|
+
...fullMetadata.additional,
|
269
|
+
chunk_info: {
|
270
|
+
chunk_index: i,
|
271
|
+
total_chunks: chunks.length,
|
272
|
+
is_chunk: true
|
273
|
+
}
|
274
|
+
}
|
275
|
+
};
|
276
|
+
// Create embedding for chunk
|
277
|
+
const embedding = await this.createEmbedding(chunks[i]);
|
278
|
+
const embeddingStr = `[${embedding.join(',')}]`;
|
279
|
+
const query = `
|
280
|
+
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector!, $expiresAt: timestamptz) {
|
281
|
+
insert_memories_one(object: {
|
282
|
+
content: $content,
|
283
|
+
agent_id: $agentId,
|
284
|
+
metadata: $metadata,
|
285
|
+
embedding: $embedding,
|
286
|
+
expires_at: $expiresAt
|
287
|
+
}) {
|
288
|
+
id
|
289
|
+
agent_id
|
290
|
+
content
|
291
|
+
metadata
|
292
|
+
embedding
|
293
|
+
created_at
|
294
|
+
updated_at
|
295
|
+
expires_at
|
296
|
+
}
|
297
|
+
}
|
298
|
+
`;
|
299
|
+
const result = await this.executeQuery(query, {
|
300
|
+
content: chunks[i],
|
301
|
+
agentId,
|
302
|
+
metadata: chunkMetadata,
|
303
|
+
embedding: embeddingStr,
|
304
|
+
expiresAt
|
305
|
+
});
|
306
|
+
// Convert snake_case to camelCase
|
307
|
+
const { agent_id, created_at, updated_at, expires_at, ...rest } = result.insert_memories_one;
|
308
|
+
const memory = {
|
309
|
+
...rest,
|
310
|
+
agentId: agent_id,
|
311
|
+
createdAt: created_at,
|
312
|
+
updatedAt: updated_at,
|
313
|
+
expiresAt: expires_at,
|
314
|
+
};
|
315
|
+
memories.push(memory);
|
316
|
+
// Link chunks sequentially
|
317
|
+
if (previousChunkId) {
|
318
|
+
await this.linkMemories(previousChunkId, memory.id, taxonomy_1.EdgeType.FOLLOWS_UP, 1.0, {
|
319
|
+
relationship: taxonomy_1.EdgeType.FOLLOWS_UP,
|
320
|
+
weight: 1.0,
|
321
|
+
bidirectional: false,
|
322
|
+
additional: { is_chunk_link: true }
|
323
|
+
});
|
324
|
+
// Also add PART_OF relationship to show these are parts of the same content
|
325
|
+
await this.linkMemories(memory.id, previousChunkId, taxonomy_1.EdgeType.PART_OF, 1.0, {
|
326
|
+
relationship: taxonomy_1.EdgeType.PART_OF,
|
327
|
+
weight: 1.0,
|
328
|
+
bidirectional: true,
|
329
|
+
additional: { is_chunk_link: true }
|
330
|
+
});
|
331
|
+
}
|
332
|
+
previousChunkId = memory.id;
|
333
|
+
}
|
334
|
+
return memories;
|
249
335
|
}
|
250
336
|
/**
|
251
337
|
* Delete a specific memory.
|
@@ -364,7 +450,7 @@ class MeshOS {
|
|
364
450
|
throw new Error(`Memory ${memoryId} not found`);
|
365
451
|
}
|
366
452
|
// Create new memory with updated content and metadata
|
367
|
-
const
|
453
|
+
const newMemories = await this.remember(content, oldMemory.agent_id, {
|
368
454
|
...oldMemory.metadata,
|
369
455
|
version: oldMemory.metadata.version + 1,
|
370
456
|
previousVersion: oldMemory.id,
|
@@ -372,14 +458,16 @@ class MeshOS {
|
|
372
458
|
});
|
373
459
|
// Create version edge if requested
|
374
460
|
if (createVersionEdge) {
|
375
|
-
|
461
|
+
// If we got multiple memories (chunks), link the first one
|
462
|
+
const firstNewMemory = Array.isArray(newMemories) ? newMemories[0] : newMemories;
|
463
|
+
await this.linkMemories(oldMemory.id, firstNewMemory.id, taxonomy_1.EdgeType.VERSION_OF, 1.0, {
|
376
464
|
relationship: taxonomy_1.EdgeType.VERSION_OF,
|
377
465
|
weight: 1.0,
|
378
466
|
bidirectional: false,
|
379
467
|
additional: { version_increment: 1 }
|
380
468
|
});
|
381
469
|
}
|
382
|
-
return
|
470
|
+
return newMemories;
|
383
471
|
}
|
384
472
|
/**
|
385
473
|
* Get memories connected to the given memory.
|
@@ -445,73 +533,86 @@ class MeshOS {
|
|
445
533
|
* Search memories by semantic similarity.
|
446
534
|
*/
|
447
535
|
async recall(options) {
|
448
|
-
const { query, agentId, limit = 5, threshold = 0.7, minResults = 1, adaptiveThreshold = true, useSemanticExpansion = true, filters } = options;
|
536
|
+
const { query, agentId, limit = 5, threshold = 0.7, minResults = 1, adaptiveThreshold = true, useSemanticExpansion = true, filters, createdAtFilter, expiresAtFilter } = options;
|
449
537
|
// First try: Direct search with initial threshold
|
450
538
|
let results = await this.recallWithThreshold({
|
451
539
|
query,
|
452
540
|
threshold,
|
453
541
|
agentId,
|
454
542
|
limit,
|
455
|
-
filters
|
543
|
+
filters,
|
544
|
+
createdAtFilter,
|
545
|
+
expiresAtFilter
|
456
546
|
});
|
457
547
|
if (results.length >= minResults) {
|
458
548
|
return results.slice(0, limit);
|
459
549
|
}
|
460
|
-
// Second try:
|
550
|
+
// Second try: If adaptive threshold is enabled, try lowering the threshold
|
461
551
|
if (adaptiveThreshold) {
|
462
552
|
let currentThreshold = threshold - 0.05;
|
463
|
-
|
553
|
+
const minThreshold = 0.3; // Don't go below this to avoid irrelevant matches
|
554
|
+
while (currentThreshold >= minThreshold && results.length < minResults) {
|
464
555
|
const newResults = await this.recallWithThreshold({
|
465
556
|
query,
|
466
557
|
threshold: currentThreshold,
|
467
558
|
agentId,
|
468
559
|
limit,
|
469
|
-
filters
|
560
|
+
filters,
|
561
|
+
createdAtFilter,
|
562
|
+
expiresAtFilter
|
470
563
|
});
|
471
|
-
// Add new
|
564
|
+
// Add new results that aren't already in the list
|
472
565
|
for (const result of newResults) {
|
473
566
|
if (!results.some(r => r.id === result.id)) {
|
474
567
|
results.push(result);
|
475
568
|
}
|
476
569
|
}
|
477
|
-
if (results.length >= minResults)
|
570
|
+
if (results.length >= minResults) {
|
478
571
|
break;
|
572
|
+
}
|
479
573
|
currentThreshold -= 0.05;
|
480
574
|
}
|
481
575
|
}
|
482
|
-
// Third try:
|
576
|
+
// Third try: If we still don't have ANY results and semantic expansion is enabled
|
483
577
|
if (results.length === 0 && useSemanticExpansion) {
|
484
578
|
const variations = await this.expandQuery(query);
|
485
579
|
const seenIds = new Map();
|
486
|
-
//
|
487
|
-
|
580
|
+
const minThreshold = 0.3; // Don't go below this to avoid irrelevant matches
|
581
|
+
// Try each variation with the original threshold first
|
582
|
+
for (const variation of variations.slice(1)) { // Skip original query as we already tried it
|
488
583
|
const variationResults = await this.recallWithThreshold({
|
489
584
|
query: variation,
|
490
585
|
threshold,
|
491
586
|
agentId,
|
492
587
|
limit,
|
493
|
-
filters
|
588
|
+
filters,
|
589
|
+
createdAtFilter,
|
590
|
+
expiresAtFilter
|
494
591
|
});
|
592
|
+
// Add new results or update if better similarity
|
495
593
|
for (const memory of variationResults) {
|
496
594
|
const existingMemory = seenIds.get(memory.id);
|
497
595
|
if (!existingMemory || (memory.similarity || 0) > (existingMemory.similarity || 0)) {
|
498
596
|
seenIds.set(memory.id, memory);
|
499
597
|
}
|
500
598
|
}
|
501
|
-
if (seenIds.size >= minResults)
|
599
|
+
if (seenIds.size >= minResults) {
|
502
600
|
break;
|
601
|
+
}
|
503
602
|
}
|
504
603
|
// If still no results, try variations with adaptive threshold
|
505
604
|
if (seenIds.size === 0 && adaptiveThreshold) {
|
506
605
|
let currentThreshold = threshold - 0.05;
|
507
|
-
while (currentThreshold >=
|
606
|
+
while (currentThreshold >= minThreshold && seenIds.size === 0) {
|
508
607
|
for (const variation of variations.slice(1)) {
|
509
608
|
const variationResults = await this.recallWithThreshold({
|
510
609
|
query: variation,
|
511
610
|
threshold: currentThreshold,
|
512
611
|
agentId,
|
513
612
|
limit,
|
514
|
-
filters
|
613
|
+
filters,
|
614
|
+
createdAtFilter,
|
615
|
+
expiresAtFilter
|
515
616
|
});
|
516
617
|
for (const memory of variationResults) {
|
517
618
|
const existingMemory = seenIds.get(memory.id);
|
@@ -519,19 +620,22 @@ class MeshOS {
|
|
519
620
|
seenIds.set(memory.id, memory);
|
520
621
|
}
|
521
622
|
}
|
522
|
-
if (seenIds.size > 0)
|
623
|
+
if (seenIds.size > 0) {
|
523
624
|
break;
|
625
|
+
}
|
524
626
|
}
|
525
|
-
if (seenIds.size > 0)
|
627
|
+
if (seenIds.size > 0) {
|
526
628
|
break;
|
629
|
+
}
|
527
630
|
currentThreshold -= 0.05;
|
528
631
|
}
|
529
632
|
}
|
633
|
+
// Update results with any found memories
|
530
634
|
if (seenIds.size > 0) {
|
531
635
|
results = Array.from(seenIds.values());
|
532
636
|
}
|
533
637
|
}
|
534
|
-
// Sort by similarity and return
|
638
|
+
// Sort by similarity and return top results
|
535
639
|
results.sort((a, b) => (b.similarity || 0) - (a.similarity || 0));
|
536
640
|
return results.slice(0, limit);
|
537
641
|
}
|
@@ -539,7 +643,7 @@ class MeshOS {
|
|
539
643
|
* Internal method to perform recall with a specific threshold.
|
540
644
|
*/
|
541
645
|
async recallWithThreshold(options) {
|
542
|
-
const { query, threshold, agentId, limit = 10, filters } = options;
|
646
|
+
const { query, threshold, agentId, limit = 10, filters, createdAtFilter, expiresAtFilter } = options;
|
543
647
|
// Create embedding for the query
|
544
648
|
const embedding = await this.createEmbedding(query);
|
545
649
|
const embeddingStr = `[${embedding.join(',')}]`;
|
@@ -550,20 +654,48 @@ class MeshOS {
|
|
550
654
|
agent_id
|
551
655
|
content
|
552
656
|
metadata
|
553
|
-
embedding
|
554
657
|
similarity
|
555
658
|
created_at
|
556
659
|
updated_at
|
660
|
+
expires_at
|
557
661
|
}
|
558
662
|
}
|
559
663
|
`;
|
664
|
+
// Process metadata filters
|
665
|
+
let metadataFilter;
|
666
|
+
if (filters) {
|
667
|
+
// Extract metadata filters
|
668
|
+
const { type, subtype, tags, relevance, version, _contains, ...additionalFilters } = filters;
|
669
|
+
metadataFilter = {};
|
670
|
+
// Add basic metadata filters
|
671
|
+
if (type)
|
672
|
+
metadataFilter.type = type;
|
673
|
+
if (subtype)
|
674
|
+
metadataFilter.subtype = subtype;
|
675
|
+
if (tags)
|
676
|
+
metadataFilter.tags = tags;
|
677
|
+
if (relevance)
|
678
|
+
metadataFilter.relevance = relevance;
|
679
|
+
if (version)
|
680
|
+
metadataFilter.version = version;
|
681
|
+
// Add array containment operations
|
682
|
+
if (_contains) {
|
683
|
+
metadataFilter._contains = _contains;
|
684
|
+
}
|
685
|
+
// Add any additional filters to the metadata.additional object
|
686
|
+
if (Object.keys(additionalFilters).length > 0) {
|
687
|
+
metadataFilter.additional = additionalFilters;
|
688
|
+
}
|
689
|
+
}
|
560
690
|
const result = await this.executeQuery(gqlQuery, {
|
561
691
|
args: {
|
562
692
|
query_embedding: embeddingStr,
|
563
693
|
match_threshold: threshold,
|
564
694
|
match_count: limit,
|
565
695
|
filter_agent_id: agentId,
|
566
|
-
|
696
|
+
metadata_filter: metadataFilter,
|
697
|
+
created_at_filter: createdAtFilter,
|
698
|
+
expires_at_filter: expiresAtFilter
|
567
699
|
}
|
568
700
|
});
|
569
701
|
return result.search_memories.map(memory => ({
|
@@ -574,7 +706,8 @@ class MeshOS {
|
|
574
706
|
embedding: memory.embedding,
|
575
707
|
similarity: memory.similarity,
|
576
708
|
createdAt: memory.created_at,
|
577
|
-
updatedAt: memory.updated_at
|
709
|
+
updatedAt: memory.updated_at,
|
710
|
+
expiresAt: memory.expires_at
|
578
711
|
}));
|
579
712
|
}
|
580
713
|
/**
|
package/dist/core/taxonomy.d.ts
CHANGED
@@ -63,7 +63,8 @@ export declare enum EdgeType {
|
|
63
63
|
CONTRADICTS = "contradicts",// Conflicting information
|
64
64
|
DEPENDS_ON = "depends_on",// Prerequisite relationship
|
65
65
|
SUMMARIZES = "summarizes",// Condensed version
|
66
|
-
INFLUENCES = "influences"
|
66
|
+
INFLUENCES = "influences",// Impact relationship
|
67
|
+
PART_OF = "part_of"
|
67
68
|
}
|
68
69
|
/**
|
69
70
|
* Relevance classification tags.
|
@@ -228,3 +229,13 @@ export declare const edgeMetadataSchema: z.ZodObject<{
|
|
228
229
|
bidirectional?: boolean | undefined;
|
229
230
|
}>;
|
230
231
|
export type EdgeMetadata = z.infer<typeof edgeMetadataSchema>;
|
232
|
+
/**
|
233
|
+
* Timestamp filter operators
|
234
|
+
*/
|
235
|
+
export interface TimestampFilter {
|
236
|
+
_gt?: string;
|
237
|
+
_gte?: string;
|
238
|
+
_lt?: string;
|
239
|
+
_lte?: string;
|
240
|
+
_eq?: string;
|
241
|
+
}
|
package/dist/core/taxonomy.js
CHANGED
@@ -73,6 +73,7 @@ var EdgeType;
|
|
73
73
|
EdgeType["DEPENDS_ON"] = "depends_on";
|
74
74
|
EdgeType["SUMMARIZES"] = "summarizes";
|
75
75
|
EdgeType["INFLUENCES"] = "influences";
|
76
|
+
EdgeType["PART_OF"] = "part_of";
|
76
77
|
})(EdgeType || (exports.EdgeType = EdgeType = {}));
|
77
78
|
/**
|
78
79
|
* Relevance classification tags.
|
package/dist/index.d.ts
CHANGED
@@ -2,5 +2,5 @@
|
|
2
2
|
* MeshOS - A lightweight multi-agent memory system with semantic search.
|
3
3
|
*/
|
4
4
|
export { Agent, Memory, MemoryEdge, MeshOS, GraphQLError, InvalidSlugError, type MeshOSConfig } from './core/client';
|
5
|
-
export { DataType, ActivitySubtype, KnowledgeSubtype, DecisionSubtype, MediaSubtype, EdgeType, RelevanceTag, type VersionInfo, type MemoryMetadata, type EdgeMetadata, } from './core/taxonomy';
|
6
|
-
export declare const VERSION = "0.1.
|
5
|
+
export { DataType, ActivitySubtype, KnowledgeSubtype, DecisionSubtype, MediaSubtype, EdgeType, RelevanceTag, CoreAgentStatus, type AgentStatus, type VersionInfo, type MemoryMetadata, type EdgeMetadata, } from './core/taxonomy';
|
6
|
+
export declare const VERSION = "0.1.9";
|
package/dist/index.js
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
* MeshOS - A lightweight multi-agent memory system with semantic search.
|
4
4
|
*/
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.VERSION = exports.RelevanceTag = exports.EdgeType = exports.MediaSubtype = exports.DecisionSubtype = exports.KnowledgeSubtype = exports.ActivitySubtype = exports.DataType = exports.InvalidSlugError = exports.GraphQLError = exports.MeshOS = void 0;
|
6
|
+
exports.VERSION = exports.CoreAgentStatus = exports.RelevanceTag = exports.EdgeType = exports.MediaSubtype = exports.DecisionSubtype = exports.KnowledgeSubtype = exports.ActivitySubtype = exports.DataType = exports.InvalidSlugError = exports.GraphQLError = exports.MeshOS = void 0;
|
7
7
|
var client_1 = require("./core/client");
|
8
8
|
Object.defineProperty(exports, "MeshOS", { enumerable: true, get: function () { return client_1.MeshOS; } });
|
9
9
|
Object.defineProperty(exports, "GraphQLError", { enumerable: true, get: function () { return client_1.GraphQLError; } });
|
@@ -17,4 +17,6 @@ Object.defineProperty(exports, "DecisionSubtype", { enumerable: true, get: funct
|
|
17
17
|
Object.defineProperty(exports, "MediaSubtype", { enumerable: true, get: function () { return taxonomy_1.MediaSubtype; } });
|
18
18
|
Object.defineProperty(exports, "EdgeType", { enumerable: true, get: function () { return taxonomy_1.EdgeType; } });
|
19
19
|
Object.defineProperty(exports, "RelevanceTag", { enumerable: true, get: function () { return taxonomy_1.RelevanceTag; } });
|
20
|
-
|
20
|
+
// Agent status types
|
21
|
+
Object.defineProperty(exports, "CoreAgentStatus", { enumerable: true, get: function () { return taxonomy_1.CoreAgentStatus; } });
|
22
|
+
exports.VERSION = '0.1.9';
|
package/package.json
CHANGED
@@ -14,4 +14,10 @@ computed_fields:
|
|
14
14
|
function:
|
15
15
|
name: search_memories
|
16
16
|
schema: public
|
17
|
+
arguments:
|
18
|
+
query_embedding: $query_embedding
|
19
|
+
match_threshold: $match_threshold
|
20
|
+
match_count: $match_count
|
21
|
+
filter_agent_id: $filter_agent_id
|
22
|
+
metadata_filter: $metadata_filter
|
17
23
|
comment: Computes similarity score for vector search
|
@@ -1,13 +1,26 @@
|
|
1
|
-
-- Drop
|
2
|
-
DROP FUNCTION IF EXISTS search_memories;
|
1
|
+
-- Drop all versions of search_memories function
|
2
|
+
DROP FUNCTION IF EXISTS public.search_memories(vector(1536), float8, integer, uuid, jsonb);
|
3
|
+
DROP FUNCTION IF EXISTS public.search_memories(vector(1536), float8, integer, uuid);
|
4
|
+
DROP FUNCTION IF EXISTS public.search_memories;
|
5
|
+
|
6
|
+
-- Drop other functions
|
3
7
|
DROP FUNCTION IF EXISTS get_connected_memories;
|
8
|
+
|
9
|
+
-- Drop triggers first
|
10
|
+
DROP TRIGGER IF EXISTS update_agents_updated_at ON public.agents;
|
11
|
+
DROP TRIGGER IF EXISTS update_memories_updated_at ON public.memories;
|
12
|
+
|
13
|
+
-- Now we can safely drop the trigger function
|
4
14
|
DROP FUNCTION IF EXISTS update_updated_at_column;
|
5
15
|
|
16
|
+
-- Drop views first
|
17
|
+
DROP VIEW IF EXISTS public.memories_with_similarity;
|
18
|
+
|
6
19
|
-- Drop tables
|
7
20
|
DROP TABLE IF EXISTS public.memory_edges;
|
8
21
|
DROP TABLE IF EXISTS public.memories;
|
9
22
|
DROP TABLE IF EXISTS public.agents;
|
10
23
|
|
11
|
-
-- Drop extensions
|
12
|
-
DROP EXTENSION IF EXISTS vector;
|
24
|
+
-- Drop extensions (with CASCADE for vector since it has dependent objects)
|
25
|
+
DROP EXTENSION IF EXISTS vector CASCADE;
|
13
26
|
DROP EXTENSION IF EXISTS "uuid-ossp";
|
@@ -0,0 +1,44 @@
|
|
1
|
+
-- Drop the existing search_memories function
|
2
|
+
DROP FUNCTION IF EXISTS public.search_memories;
|
3
|
+
|
4
|
+
-- Create the updated search_memories function with metadata filtering
|
5
|
+
CREATE OR REPLACE FUNCTION public.search_memories(
|
6
|
+
query_embedding vector(1536),
|
7
|
+
match_threshold float8,
|
8
|
+
match_count integer,
|
9
|
+
filter_agent_id uuid DEFAULT NULL,
|
10
|
+
metadata_filter jsonb DEFAULT NULL
|
11
|
+
)
|
12
|
+
RETURNS SETOF public.memories_with_similarity
|
13
|
+
LANGUAGE sql
|
14
|
+
STABLE
|
15
|
+
AS $$
|
16
|
+
WITH normalized_query AS (
|
17
|
+
SELECT l2_normalize(query_embedding) AS normalized_vector
|
18
|
+
)
|
19
|
+
SELECT
|
20
|
+
m.id,
|
21
|
+
m.agent_id,
|
22
|
+
m.content,
|
23
|
+
m.metadata,
|
24
|
+
m.embedding,
|
25
|
+
m.created_at,
|
26
|
+
m.updated_at,
|
27
|
+
-(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) as similarity
|
28
|
+
FROM memories m
|
29
|
+
WHERE
|
30
|
+
CASE
|
31
|
+
WHEN filter_agent_id IS NOT NULL THEN m.agent_id = filter_agent_id
|
32
|
+
ELSE TRUE
|
33
|
+
END
|
34
|
+
AND CASE
|
35
|
+
WHEN metadata_filter IS NOT NULL THEN m.metadata @> metadata_filter
|
36
|
+
ELSE TRUE
|
37
|
+
END
|
38
|
+
AND -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) >= match_threshold
|
39
|
+
ORDER BY -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) DESC
|
40
|
+
LIMIT match_count;
|
41
|
+
$$;
|
42
|
+
|
43
|
+
-- Track the function in Hasura
|
44
|
+
COMMENT ON FUNCTION public.search_memories IS E'@graphql({"type": "Query"})';
|
@@ -0,0 +1,55 @@
|
|
1
|
+
-- Drop the updated search_memories function
|
2
|
+
DROP FUNCTION IF EXISTS public.search_memories(vector(1536), float8, integer, uuid, jsonb, jsonb, jsonb);
|
3
|
+
|
4
|
+
-- Remove expires_at column
|
5
|
+
ALTER TABLE public.memories DROP COLUMN expires_at;
|
6
|
+
|
7
|
+
-- Drop and recreate the view without expires_at
|
8
|
+
DROP VIEW IF EXISTS public.memories_with_similarity;
|
9
|
+
CREATE OR REPLACE VIEW public.memories_with_similarity AS
|
10
|
+
SELECT
|
11
|
+
m.*,
|
12
|
+
0::float8 as similarity
|
13
|
+
FROM memories m;
|
14
|
+
|
15
|
+
-- Restore the previous version of search_memories from 2_metadata_filtering
|
16
|
+
CREATE OR REPLACE FUNCTION public.search_memories(
|
17
|
+
query_embedding vector(1536),
|
18
|
+
match_threshold float8,
|
19
|
+
match_count integer,
|
20
|
+
filter_agent_id uuid DEFAULT NULL,
|
21
|
+
metadata_filter jsonb DEFAULT NULL
|
22
|
+
)
|
23
|
+
RETURNS SETOF public.memories_with_similarity
|
24
|
+
LANGUAGE sql
|
25
|
+
STABLE
|
26
|
+
AS $$
|
27
|
+
WITH normalized_query AS (
|
28
|
+
SELECT l2_normalize(query_embedding) AS normalized_vector
|
29
|
+
)
|
30
|
+
SELECT
|
31
|
+
m.id,
|
32
|
+
m.agent_id,
|
33
|
+
m.content,
|
34
|
+
m.metadata,
|
35
|
+
m.embedding,
|
36
|
+
m.created_at,
|
37
|
+
m.updated_at,
|
38
|
+
-(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) as similarity
|
39
|
+
FROM memories m
|
40
|
+
WHERE
|
41
|
+
CASE
|
42
|
+
WHEN filter_agent_id IS NOT NULL THEN m.agent_id = filter_agent_id
|
43
|
+
ELSE TRUE
|
44
|
+
END
|
45
|
+
AND CASE
|
46
|
+
WHEN metadata_filter IS NOT NULL THEN m.metadata @> metadata_filter
|
47
|
+
ELSE TRUE
|
48
|
+
END
|
49
|
+
AND -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) >= match_threshold
|
50
|
+
ORDER BY -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) DESC
|
51
|
+
LIMIT match_count;
|
52
|
+
$$;
|
53
|
+
|
54
|
+
-- Track the function in Hasura
|
55
|
+
COMMENT ON FUNCTION public.search_memories IS E'@graphql({"type": "Query"})';
|
@@ -0,0 +1,108 @@
|
|
1
|
+
-- Add expires_at column to memories table
|
2
|
+
ALTER TABLE public.memories ADD COLUMN expires_at TIMESTAMPTZ;
|
3
|
+
|
4
|
+
-- Create a view for memories with similarity that includes all fields
|
5
|
+
DROP VIEW IF EXISTS public.memories_with_similarity;
|
6
|
+
CREATE OR REPLACE VIEW public.memories_with_similarity AS
|
7
|
+
SELECT
|
8
|
+
m.*,
|
9
|
+
0::float8 as similarity -- Default similarity, will be replaced in search
|
10
|
+
FROM memories m;
|
11
|
+
|
12
|
+
-- Drop the existing search_memories function
|
13
|
+
DROP FUNCTION IF EXISTS public.search_memories;
|
14
|
+
|
15
|
+
-- Create the updated search_memories function with standard Hasura filtering
|
16
|
+
CREATE OR REPLACE FUNCTION public.search_memories(
|
17
|
+
query_embedding vector(1536),
|
18
|
+
match_threshold float8,
|
19
|
+
match_count integer,
|
20
|
+
filter_agent_id uuid DEFAULT NULL,
|
21
|
+
metadata_filter jsonb DEFAULT NULL,
|
22
|
+
created_at_filter jsonb DEFAULT NULL,
|
23
|
+
expires_at_filter jsonb DEFAULT NULL
|
24
|
+
)
|
25
|
+
RETURNS SETOF public.memories_with_similarity
|
26
|
+
LANGUAGE sql
|
27
|
+
STABLE
|
28
|
+
AS $$
|
29
|
+
WITH normalized_query AS (
|
30
|
+
SELECT l2_normalize(query_embedding) AS normalized_vector
|
31
|
+
)
|
32
|
+
SELECT
|
33
|
+
m.id,
|
34
|
+
m.agent_id,
|
35
|
+
m.content,
|
36
|
+
m.metadata,
|
37
|
+
m.embedding,
|
38
|
+
m.created_at,
|
39
|
+
m.updated_at,
|
40
|
+
m.expires_at,
|
41
|
+
-(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) as similarity
|
42
|
+
FROM memories m
|
43
|
+
WHERE
|
44
|
+
CASE
|
45
|
+
WHEN filter_agent_id IS NOT NULL THEN m.agent_id = filter_agent_id
|
46
|
+
ELSE TRUE
|
47
|
+
END
|
48
|
+
AND CASE
|
49
|
+
WHEN metadata_filter IS NOT NULL THEN m.metadata @> metadata_filter
|
50
|
+
ELSE TRUE
|
51
|
+
END
|
52
|
+
AND CASE
|
53
|
+
WHEN created_at_filter IS NOT NULL THEN (
|
54
|
+
CASE
|
55
|
+
WHEN created_at_filter ? '_gt' THEN m.created_at > (created_at_filter->>'_gt')::timestamptz
|
56
|
+
ELSE TRUE
|
57
|
+
END
|
58
|
+
AND CASE
|
59
|
+
WHEN created_at_filter ? '_gte' THEN m.created_at >= (created_at_filter->>'_gte')::timestamptz
|
60
|
+
ELSE TRUE
|
61
|
+
END
|
62
|
+
AND CASE
|
63
|
+
WHEN created_at_filter ? '_lt' THEN m.created_at < (created_at_filter->>'_lt')::timestamptz
|
64
|
+
ELSE TRUE
|
65
|
+
END
|
66
|
+
AND CASE
|
67
|
+
WHEN created_at_filter ? '_lte' THEN m.created_at <= (created_at_filter->>'_lte')::timestamptz
|
68
|
+
ELSE TRUE
|
69
|
+
END
|
70
|
+
AND CASE
|
71
|
+
WHEN created_at_filter ? '_eq' THEN m.created_at = (created_at_filter->>'_eq')::timestamptz
|
72
|
+
ELSE TRUE
|
73
|
+
END
|
74
|
+
)
|
75
|
+
ELSE TRUE
|
76
|
+
END
|
77
|
+
AND CASE
|
78
|
+
WHEN expires_at_filter IS NOT NULL THEN (
|
79
|
+
CASE
|
80
|
+
WHEN expires_at_filter ? '_gt' THEN m.expires_at > (expires_at_filter->>'_gt')::timestamptz
|
81
|
+
ELSE TRUE
|
82
|
+
END
|
83
|
+
AND CASE
|
84
|
+
WHEN expires_at_filter ? '_gte' THEN m.expires_at >= (expires_at_filter->>'_gte')::timestamptz
|
85
|
+
ELSE TRUE
|
86
|
+
END
|
87
|
+
AND CASE
|
88
|
+
WHEN expires_at_filter ? '_lt' THEN m.expires_at < (expires_at_filter->>'_lt')::timestamptz
|
89
|
+
ELSE TRUE
|
90
|
+
END
|
91
|
+
AND CASE
|
92
|
+
WHEN expires_at_filter ? '_lte' THEN m.expires_at <= (expires_at_filter->>'_lte')::timestamptz
|
93
|
+
ELSE TRUE
|
94
|
+
END
|
95
|
+
AND CASE
|
96
|
+
WHEN expires_at_filter ? '_eq' THEN m.expires_at = (expires_at_filter->>'_eq')::timestamptz
|
97
|
+
ELSE TRUE
|
98
|
+
END
|
99
|
+
)
|
100
|
+
ELSE TRUE
|
101
|
+
END
|
102
|
+
AND -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) >= match_threshold
|
103
|
+
ORDER BY -(m.embedding <#> (SELECT normalized_vector FROM normalized_query)) DESC
|
104
|
+
LIMIT match_count;
|
105
|
+
$$;
|
106
|
+
|
107
|
+
-- Track the function in Hasura
|
108
|
+
COMMENT ON FUNCTION public.search_memories IS E'@graphql({"type": "Query"})';
|