@prmichaelsen/remember-mcp 0.2.4 → 0.2.7
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 +42 -13
- package/agent/progress.yaml +141 -30
- package/agent/tasks/task-20-fix-weaviate-v3-filters.md +450 -0
- package/dist/server-factory.js +614 -123
- package/dist/server.js +605 -170
- package/dist/services/preferences-database.service.d.ts +22 -0
- package/dist/tools/get-preferences.d.ts +41 -0
- package/dist/tools/search-memory.d.ts +1 -1
- package/dist/tools/set-preference.d.ts +185 -0
- package/dist/types/preferences.d.ts +284 -0
- package/dist/utils/logger.d.ts +4 -4
- package/dist/utils/weaviate-filters.d.ts +37 -0
- package/dist/utils/weaviate-filters.spec.d.ts +5 -0
- package/package.json +1 -1
- package/src/server-factory.spec.ts +4 -2
- package/src/server-factory.ts +26 -2
- package/src/server.ts +15 -62
- package/src/services/preferences-database.service.ts +120 -0
- package/src/tools/create-memory.ts +1 -0
- package/src/tools/get-preferences.ts +111 -0
- package/src/tools/query-memory.ts +5 -57
- package/src/tools/search-memory.ts +52 -83
- package/src/tools/set-preference.ts +145 -0
- package/src/types/preferences.ts +280 -0
- package/src/utils/logger.ts +25 -8
- package/src/utils/weaviate-filters.spec.ts +515 -0
- package/src/utils/weaviate-filters.ts +207 -0
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weaviate v3 Filter Builder Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides helper functions to build Weaviate v3 filters using the fluent API.
|
|
5
|
+
* Replaces old v2 filter format (path/operator/valueText) with v3 collection.filter.byProperty()
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { SearchFilters } from '../types/memory.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build filters for searching both memories and relationships
|
|
12
|
+
* Uses OR logic: (doc_type=memory AND memory_filters) OR (doc_type=relationship AND relationship_filters)
|
|
13
|
+
*
|
|
14
|
+
* @param collection - Weaviate collection instance
|
|
15
|
+
* @param filters - Optional search filters
|
|
16
|
+
* @returns Combined filter or undefined if no filters
|
|
17
|
+
*/
|
|
18
|
+
export function buildCombinedSearchFilters(
|
|
19
|
+
collection: any,
|
|
20
|
+
filters?: SearchFilters
|
|
21
|
+
): any {
|
|
22
|
+
// Build memory-specific filters
|
|
23
|
+
const memoryFilters = buildDocTypeFilters(collection, 'memory', filters);
|
|
24
|
+
|
|
25
|
+
// Build relationship-specific filters
|
|
26
|
+
const relationshipFilters = buildDocTypeFilters(collection, 'relationship', filters);
|
|
27
|
+
|
|
28
|
+
// Combine with OR: search both memories and relationships
|
|
29
|
+
if (memoryFilters && relationshipFilters) {
|
|
30
|
+
return combineFiltersWithOr([memoryFilters, relationshipFilters]);
|
|
31
|
+
} else if (memoryFilters) {
|
|
32
|
+
return memoryFilters;
|
|
33
|
+
} else if (relationshipFilters) {
|
|
34
|
+
return relationshipFilters;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build filters for a specific doc_type (memory or relationship)
|
|
42
|
+
*
|
|
43
|
+
* @param collection - Weaviate collection instance
|
|
44
|
+
* @param docType - 'memory' or 'relationship'
|
|
45
|
+
* @param filters - Optional search filters
|
|
46
|
+
* @returns Combined filter for this doc_type
|
|
47
|
+
*/
|
|
48
|
+
function buildDocTypeFilters(
|
|
49
|
+
collection: any,
|
|
50
|
+
docType: 'memory' | 'relationship',
|
|
51
|
+
filters?: SearchFilters
|
|
52
|
+
): any {
|
|
53
|
+
const filterList: any[] = [];
|
|
54
|
+
|
|
55
|
+
// Always filter by doc_type
|
|
56
|
+
filterList.push(
|
|
57
|
+
collection.filter.byProperty('doc_type').equal(docType)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Type filter (content type) - only applies to memories, not relationships
|
|
61
|
+
if (docType === 'memory' && filters?.types && filters.types.length > 0) {
|
|
62
|
+
if (filters.types.length === 1) {
|
|
63
|
+
filterList.push(
|
|
64
|
+
collection.filter.byProperty('type').equal(filters.types[0])
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
filterList.push(
|
|
68
|
+
collection.filter.byProperty('type').containsAny(filters.types)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Weight filter (minimum) - applies to both memories and relationships
|
|
74
|
+
if (filters?.weight_min !== undefined) {
|
|
75
|
+
filterList.push(
|
|
76
|
+
collection.filter.byProperty('weight').greaterThanOrEqual(filters.weight_min)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Weight filter (maximum)
|
|
81
|
+
if (filters?.weight_max !== undefined) {
|
|
82
|
+
filterList.push(
|
|
83
|
+
collection.filter.byProperty('weight').lessThanOrEqual(filters.weight_max)
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Trust filter (minimum) - applies to both
|
|
88
|
+
if (filters?.trust_min !== undefined) {
|
|
89
|
+
filterList.push(
|
|
90
|
+
collection.filter.byProperty('trust').greaterThanOrEqual(filters.trust_min)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Trust filter (maximum)
|
|
95
|
+
if (filters?.trust_max !== undefined) {
|
|
96
|
+
filterList.push(
|
|
97
|
+
collection.filter.byProperty('trust').lessThanOrEqual(filters.trust_max)
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Date range filter (from) - applies to both
|
|
102
|
+
if (filters?.date_from) {
|
|
103
|
+
filterList.push(
|
|
104
|
+
collection.filter.byProperty('created_at').greaterThanOrEqual(new Date(filters.date_from))
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Date range filter (to)
|
|
109
|
+
if (filters?.date_to) {
|
|
110
|
+
filterList.push(
|
|
111
|
+
collection.filter.byProperty('created_at').lessThanOrEqual(new Date(filters.date_to))
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Tags filter - applies to both
|
|
116
|
+
if (filters?.tags && filters.tags.length > 0) {
|
|
117
|
+
if (filters.tags.length === 1) {
|
|
118
|
+
filterList.push(
|
|
119
|
+
collection.filter.byProperty('tags').containsAny([filters.tags[0]])
|
|
120
|
+
);
|
|
121
|
+
} else {
|
|
122
|
+
filterList.push(
|
|
123
|
+
collection.filter.byProperty('tags').containsAny(filters.tags)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Combine filters with AND
|
|
129
|
+
return combineFiltersWithAnd(filterList);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Build filters for memory-only search (backward compatibility)
|
|
134
|
+
*
|
|
135
|
+
* @param collection - Weaviate collection instance
|
|
136
|
+
* @param filters - Optional search filters
|
|
137
|
+
* @returns Combined filter or undefined if no filters
|
|
138
|
+
*/
|
|
139
|
+
export function buildMemoryOnlyFilters(
|
|
140
|
+
collection: any,
|
|
141
|
+
filters?: SearchFilters
|
|
142
|
+
): any {
|
|
143
|
+
return buildDocTypeFilters(collection, 'memory', filters);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Build filters specifically for relationship-only search
|
|
148
|
+
*
|
|
149
|
+
* @param collection - Weaviate collection instance
|
|
150
|
+
* @param filters - Optional search filters
|
|
151
|
+
* @returns Combined filter or undefined if no filters
|
|
152
|
+
*/
|
|
153
|
+
export function buildRelationshipOnlyFilters(
|
|
154
|
+
collection: any,
|
|
155
|
+
filters?: SearchFilters
|
|
156
|
+
): any {
|
|
157
|
+
return buildDocTypeFilters(collection, 'relationship', filters);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Combine multiple filters with AND logic
|
|
162
|
+
*
|
|
163
|
+
* @param filters - Array of filter objects
|
|
164
|
+
* @returns Combined filter or undefined
|
|
165
|
+
*/
|
|
166
|
+
function combineFiltersWithAnd(filters: any[]): any {
|
|
167
|
+
if (filters.length === 0) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
if (filters.length === 1) {
|
|
171
|
+
return filters[0];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Weaviate v3 uses operator/operands structure for combining filters
|
|
175
|
+
return {
|
|
176
|
+
operator: 'And',
|
|
177
|
+
operands: filters
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Combine multiple filters with OR logic
|
|
183
|
+
*
|
|
184
|
+
* @param filters - Array of filter objects
|
|
185
|
+
* @returns Combined filter or undefined
|
|
186
|
+
*/
|
|
187
|
+
function combineFiltersWithOr(filters: any[]): any {
|
|
188
|
+
if (filters.length === 0) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
if (filters.length === 1) {
|
|
192
|
+
return filters[0];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Weaviate v3 uses operator/operands structure for combining filters
|
|
196
|
+
return {
|
|
197
|
+
operator: 'Or',
|
|
198
|
+
operands: filters
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Helper to check if a filter result is empty
|
|
204
|
+
*/
|
|
205
|
+
export function hasFilters(filter: any): boolean {
|
|
206
|
+
return filter !== undefined && filter !== null;
|
|
207
|
+
}
|