@props-labs/mesh-os 0.1.8 → 0.1.10
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/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"})';
|