@props-labs/mesh-os 0.1.9 → 0.1.11
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/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
|
*/
|
@@ -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.
|
@@ -143,4 +146,18 @@ export declare class MeshOS {
|
|
143
146
|
* Update an agent's status.
|
144
147
|
*/
|
145
148
|
updateAgentStatus(agentId: string, status: AgentStatus): Promise<Agent>;
|
149
|
+
/**
|
150
|
+
* Query memories with flexible filtering, sorting, and pagination.
|
151
|
+
*/
|
152
|
+
getMemories(options: {
|
153
|
+
where?: Record<string, unknown>;
|
154
|
+
orderBy?: Array<{
|
155
|
+
column: string;
|
156
|
+
order: 'asc' | 'desc';
|
157
|
+
}>;
|
158
|
+
limit?: number;
|
159
|
+
offset?: number;
|
160
|
+
distinct?: boolean;
|
161
|
+
distinctOn?: string[];
|
162
|
+
}): Promise<Memory[]>;
|
146
163
|
}
|
package/dist/core/client.js
CHANGED
@@ -199,7 +199,7 @@ class MeshOS {
|
|
199
199
|
/**
|
200
200
|
* Store a new memory.
|
201
201
|
*/
|
202
|
-
async remember(content, agentId, metadata) {
|
202
|
+
async remember(content, agentId, metadata, expiresAt) {
|
203
203
|
// Create default metadata if none provided
|
204
204
|
const fullMetadata = taxonomy_1.memoryMetadataSchema.parse({
|
205
205
|
type: taxonomy_1.DataType.KNOWLEDGE,
|
@@ -217,12 +217,13 @@ class MeshOS {
|
|
217
217
|
const embedding = await this.createEmbedding(content);
|
218
218
|
const embeddingStr = `[${embedding.join(',')}]`;
|
219
219
|
const query = `
|
220
|
-
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector
|
220
|
+
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector!, $expiresAt: timestamptz) {
|
221
221
|
insert_memories_one(object: {
|
222
222
|
content: $content,
|
223
223
|
agent_id: $agentId,
|
224
224
|
metadata: $metadata,
|
225
|
-
embedding: $embedding
|
225
|
+
embedding: $embedding,
|
226
|
+
expires_at: $expiresAt
|
226
227
|
}) {
|
227
228
|
id
|
228
229
|
agent_id
|
@@ -231,6 +232,7 @@ class MeshOS {
|
|
231
232
|
embedding
|
232
233
|
created_at
|
233
234
|
updated_at
|
235
|
+
expires_at
|
234
236
|
}
|
235
237
|
}
|
236
238
|
`;
|
@@ -238,15 +240,17 @@ class MeshOS {
|
|
238
240
|
content,
|
239
241
|
agentId,
|
240
242
|
metadata: fullMetadata,
|
241
|
-
embedding: embeddingStr
|
243
|
+
embedding: embeddingStr,
|
244
|
+
expiresAt
|
242
245
|
});
|
243
246
|
// Convert snake_case to camelCase
|
244
|
-
const { agent_id, created_at, updated_at, ...rest } = result.insert_memories_one;
|
247
|
+
const { agent_id, created_at, updated_at, expires_at, ...rest } = result.insert_memories_one;
|
245
248
|
return {
|
246
249
|
...rest,
|
247
250
|
agentId: agent_id,
|
248
251
|
createdAt: created_at,
|
249
252
|
updatedAt: updated_at,
|
253
|
+
expiresAt: expires_at,
|
250
254
|
};
|
251
255
|
}
|
252
256
|
// Split content into chunks
|
@@ -273,12 +277,13 @@ class MeshOS {
|
|
273
277
|
const embedding = await this.createEmbedding(chunks[i]);
|
274
278
|
const embeddingStr = `[${embedding.join(',')}]`;
|
275
279
|
const query = `
|
276
|
-
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector
|
280
|
+
mutation Remember($content: String!, $agentId: uuid!, $metadata: jsonb!, $embedding: vector!, $expiresAt: timestamptz) {
|
277
281
|
insert_memories_one(object: {
|
278
282
|
content: $content,
|
279
283
|
agent_id: $agentId,
|
280
284
|
metadata: $metadata,
|
281
|
-
embedding: $embedding
|
285
|
+
embedding: $embedding,
|
286
|
+
expires_at: $expiresAt
|
282
287
|
}) {
|
283
288
|
id
|
284
289
|
agent_id
|
@@ -287,6 +292,7 @@ class MeshOS {
|
|
287
292
|
embedding
|
288
293
|
created_at
|
289
294
|
updated_at
|
295
|
+
expires_at
|
290
296
|
}
|
291
297
|
}
|
292
298
|
`;
|
@@ -294,15 +300,17 @@ class MeshOS {
|
|
294
300
|
content: chunks[i],
|
295
301
|
agentId,
|
296
302
|
metadata: chunkMetadata,
|
297
|
-
embedding: embeddingStr
|
303
|
+
embedding: embeddingStr,
|
304
|
+
expiresAt
|
298
305
|
});
|
299
306
|
// Convert snake_case to camelCase
|
300
|
-
const { agent_id, created_at, updated_at, ...rest } = result.insert_memories_one;
|
307
|
+
const { agent_id, created_at, updated_at, expires_at, ...rest } = result.insert_memories_one;
|
301
308
|
const memory = {
|
302
309
|
...rest,
|
303
310
|
agentId: agent_id,
|
304
311
|
createdAt: created_at,
|
305
312
|
updatedAt: updated_at,
|
313
|
+
expiresAt: expires_at,
|
306
314
|
};
|
307
315
|
memories.push(memory);
|
308
316
|
// Link chunks sequentially
|
@@ -525,14 +533,16 @@ class MeshOS {
|
|
525
533
|
* Search memories by semantic similarity.
|
526
534
|
*/
|
527
535
|
async recall(options) {
|
528
|
-
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;
|
529
537
|
// First try: Direct search with initial threshold
|
530
538
|
let results = await this.recallWithThreshold({
|
531
539
|
query,
|
532
540
|
threshold,
|
533
541
|
agentId,
|
534
542
|
limit,
|
535
|
-
filters
|
543
|
+
filters,
|
544
|
+
createdAtFilter,
|
545
|
+
expiresAtFilter
|
536
546
|
});
|
537
547
|
if (results.length >= minResults) {
|
538
548
|
return results.slice(0, limit);
|
@@ -547,7 +557,9 @@ class MeshOS {
|
|
547
557
|
threshold: currentThreshold,
|
548
558
|
agentId,
|
549
559
|
limit,
|
550
|
-
filters
|
560
|
+
filters,
|
561
|
+
createdAtFilter,
|
562
|
+
expiresAtFilter
|
551
563
|
});
|
552
564
|
// Add new results that aren't already in the list
|
553
565
|
for (const result of newResults) {
|
@@ -573,7 +585,9 @@ class MeshOS {
|
|
573
585
|
threshold,
|
574
586
|
agentId,
|
575
587
|
limit,
|
576
|
-
filters
|
588
|
+
filters,
|
589
|
+
createdAtFilter,
|
590
|
+
expiresAtFilter
|
577
591
|
});
|
578
592
|
// Add new results or update if better similarity
|
579
593
|
for (const memory of variationResults) {
|
@@ -596,7 +610,9 @@ class MeshOS {
|
|
596
610
|
threshold: currentThreshold,
|
597
611
|
agentId,
|
598
612
|
limit,
|
599
|
-
filters
|
613
|
+
filters,
|
614
|
+
createdAtFilter,
|
615
|
+
expiresAtFilter
|
600
616
|
});
|
601
617
|
for (const memory of variationResults) {
|
602
618
|
const existingMemory = seenIds.get(memory.id);
|
@@ -627,7 +643,7 @@ class MeshOS {
|
|
627
643
|
* Internal method to perform recall with a specific threshold.
|
628
644
|
*/
|
629
645
|
async recallWithThreshold(options) {
|
630
|
-
const { query, threshold, agentId, limit = 10, filters } = options;
|
646
|
+
const { query, threshold, agentId, limit = 10, filters, createdAtFilter, expiresAtFilter } = options;
|
631
647
|
// Create embedding for the query
|
632
648
|
const embedding = await this.createEmbedding(query);
|
633
649
|
const embeddingStr = `[${embedding.join(',')}]`;
|
@@ -638,10 +654,10 @@ class MeshOS {
|
|
638
654
|
agent_id
|
639
655
|
content
|
640
656
|
metadata
|
641
|
-
embedding
|
642
657
|
similarity
|
643
658
|
created_at
|
644
659
|
updated_at
|
660
|
+
expires_at
|
645
661
|
}
|
646
662
|
}
|
647
663
|
`;
|
@@ -677,7 +693,9 @@ class MeshOS {
|
|
677
693
|
match_threshold: threshold,
|
678
694
|
match_count: limit,
|
679
695
|
filter_agent_id: agentId,
|
680
|
-
metadata_filter: metadataFilter
|
696
|
+
metadata_filter: metadataFilter,
|
697
|
+
created_at_filter: createdAtFilter,
|
698
|
+
expires_at_filter: expiresAtFilter
|
681
699
|
}
|
682
700
|
});
|
683
701
|
return result.search_memories.map(memory => ({
|
@@ -688,7 +706,8 @@ class MeshOS {
|
|
688
706
|
embedding: memory.embedding,
|
689
707
|
similarity: memory.similarity,
|
690
708
|
createdAt: memory.created_at,
|
691
|
-
updatedAt: memory.updated_at
|
709
|
+
updatedAt: memory.updated_at,
|
710
|
+
expiresAt: memory.expires_at
|
692
711
|
}));
|
693
712
|
}
|
694
713
|
/**
|
@@ -719,5 +738,56 @@ class MeshOS {
|
|
719
738
|
}
|
720
739
|
return result.update_agents_by_pk;
|
721
740
|
}
|
741
|
+
/**
|
742
|
+
* Query memories with flexible filtering, sorting, and pagination.
|
743
|
+
*/
|
744
|
+
async getMemories(options) {
|
745
|
+
const { where, orderBy, limit, offset, distinct, distinctOn } = options;
|
746
|
+
// Build the GraphQL query dynamically
|
747
|
+
const query = `
|
748
|
+
query GetMemories(
|
749
|
+
$where: memories_bool_exp,
|
750
|
+
$orderBy: [memories_order_by!],
|
751
|
+
$limit: Int,
|
752
|
+
$offset: Int,
|
753
|
+
$distinctOn: [memories_select_column!]
|
754
|
+
) {
|
755
|
+
memories(
|
756
|
+
where: $where,
|
757
|
+
order_by: $orderBy,
|
758
|
+
limit: $limit,
|
759
|
+
offset: $offset,
|
760
|
+
distinct: ${distinct ? 'true' : 'false'},
|
761
|
+
distinct_on: $distinctOn
|
762
|
+
) {
|
763
|
+
id
|
764
|
+
agent_id
|
765
|
+
content
|
766
|
+
metadata
|
767
|
+
embedding
|
768
|
+
created_at
|
769
|
+
updated_at
|
770
|
+
expires_at
|
771
|
+
}
|
772
|
+
}
|
773
|
+
`;
|
774
|
+
const result = await this.executeQuery(query, {
|
775
|
+
where,
|
776
|
+
orderBy,
|
777
|
+
limit,
|
778
|
+
offset,
|
779
|
+
distinctOn
|
780
|
+
});
|
781
|
+
return result.memories.map(memory => ({
|
782
|
+
id: memory.id,
|
783
|
+
agentId: memory.agent_id,
|
784
|
+
content: memory.content,
|
785
|
+
metadata: memory.metadata,
|
786
|
+
embedding: memory.embedding,
|
787
|
+
createdAt: memory.created_at,
|
788
|
+
updatedAt: memory.updated_at,
|
789
|
+
expiresAt: memory.expires_at
|
790
|
+
}));
|
791
|
+
}
|
722
792
|
}
|
723
793
|
exports.MeshOS = MeshOS;
|
package/dist/core/taxonomy.d.ts
CHANGED
@@ -229,3 +229,13 @@ export declare const edgeMetadataSchema: z.ZodObject<{
|
|
229
229
|
bidirectional?: boolean | undefined;
|
230
230
|
}>;
|
231
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/package.json
CHANGED
@@ -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"})';
|