@prmichaelsen/remember-mcp 3.0.0 → 3.12.0
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/AGENT.md +296 -250
- package/CHANGELOG.md +338 -0
- package/README.md +68 -45
- package/agent/commands/acp.clarification-create.md +382 -0
- package/agent/commands/acp.project-info.md +309 -0
- package/agent/commands/acp.project-remove.md +379 -0
- package/agent/commands/acp.project-update.md +296 -0
- package/agent/commands/acp.task-create.md +17 -9
- package/agent/commands/git.commit.md +13 -1
- package/agent/design/comment-memory-type.md +2 -2
- package/agent/design/local.collaborative-memory-sync.md +265 -0
- package/agent/design/local.content-flags.md +210 -0
- package/agent/design/local.ghost-persona-system.md +273 -0
- package/agent/design/local.group-acl-integration.md +338 -0
- package/agent/design/local.memory-acl-schema.md +352 -0
- package/agent/design/local.memory-collection-pattern-v2.md +348 -0
- package/agent/design/local.moderation-and-space-config.md +257 -0
- package/agent/design/local.v2-api-reference.md +621 -0
- package/agent/design/local.v2-migration-guide.md +191 -0
- package/agent/design/local.v2-usage-examples.md +265 -0
- package/agent/design/permissions-storage-architecture.md +11 -3
- package/agent/design/trust-escalation-prevention.md +9 -2
- package/agent/design/trust-system-implementation.md +12 -3
- package/agent/milestones/milestone-14-memory-collection-v2.md +182 -0
- package/agent/milestones/milestone-15-moderation-space-config.md +126 -0
- package/agent/progress.yaml +628 -49
- package/agent/scripts/acp.common.sh +2 -0
- package/agent/scripts/acp.install.sh +11 -1
- package/agent/scripts/acp.package-install-optimized.sh +454 -0
- package/agent/scripts/acp.package-install.sh +247 -300
- package/agent/scripts/acp.project-info.sh +218 -0
- package/agent/scripts/acp.project-remove.sh +302 -0
- package/agent/scripts/acp.project-update.sh +296 -0
- package/agent/scripts/acp.yaml-parser.sh +128 -10
- package/agent/tasks/milestone-14-memory-collection-v2/task-165-core-infrastructure-setup.md +171 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-166-update-remember-publish.md +191 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-167-update-remember-retract.md +186 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-168-implement-remember-revise.md +184 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-169-update-remember-search-space.md +179 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-170-update-remember-create-update.md +139 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-172-performance-testing-optimization.md +161 -0
- package/agent/tasks/milestone-14-memory-collection-v2/task-173-documentation-examples.md +258 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-174-add-moderation-schema-fields.md +57 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-175-create-space-config-service.md +64 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-176-wire-moderation-publish-flow.md +45 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-177-add-moderation-search-filters.md +70 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-178-create-remember-moderate-tool.md +69 -0
- package/agent/tasks/milestone-15-moderation-space-config/task-179-documentation-integration-tests.md +58 -0
- package/agent/tasks/milestone-16-ghost-system/task-187-ghost-config-firestore.md +41 -0
- package/agent/tasks/milestone-16-ghost-system/task-188-trust-filter-integration.md +44 -0
- package/agent/tasks/milestone-16-ghost-system/task-189-ghost-memory-filtering.md +43 -0
- package/agent/tasks/milestone-16-ghost-system/task-190-ghost-config-tools.md +45 -0
- package/agent/tasks/milestone-16-ghost-system/task-191-escalation-firestore.md +38 -0
- package/agent/tasks/milestone-16-ghost-system/task-192-documentation-verification.md +39 -0
- package/agent/tasks/milestone-7-trust-permissions/task-180-access-result-permission-types.md +69 -0
- package/agent/tasks/milestone-7-trust-permissions/task-181-firestore-permissions-access-logs.md +56 -0
- package/agent/tasks/milestone-7-trust-permissions/task-182-trust-enforcement-service.md +68 -0
- package/agent/tasks/milestone-7-trust-permissions/task-183-access-control-service.md +70 -0
- package/agent/tasks/milestone-7-trust-permissions/task-184-permission-tools.md +79 -0
- package/agent/tasks/milestone-7-trust-permissions/task-185-wire-trust-into-search-query.md +55 -0
- package/agent/tasks/milestone-7-trust-permissions/task-186-documentation-verification.md +56 -0
- package/agent/tasks/task-76-fix-indexnullstate-schema-bug.md +197 -0
- package/dist/collections/composite-ids.d.ts +106 -0
- package/dist/collections/core-infrastructure.spec.d.ts +11 -0
- package/dist/collections/dot-notation.d.ts +106 -0
- package/dist/collections/tracking-arrays.d.ts +176 -0
- package/dist/constants/content-types.d.ts +1 -0
- package/dist/schema/v2-collections-comments.spec.d.ts +8 -0
- package/dist/schema/v2-collections.d.ts +210 -0
- package/dist/server-factory.d.ts +15 -0
- package/dist/server-factory.js +2798 -1029
- package/dist/server.js +2526 -1012
- package/dist/services/access-control.d.ts +103 -0
- package/dist/services/access-control.spec.d.ts +2 -0
- package/dist/services/credentials-provider.d.ts +24 -0
- package/dist/services/credentials-provider.spec.d.ts +2 -0
- package/dist/services/escalation.service.d.ts +22 -0
- package/dist/services/escalation.service.spec.d.ts +2 -0
- package/dist/services/ghost-config.service.d.ts +55 -0
- package/dist/services/ghost-config.service.spec.d.ts +2 -0
- package/dist/services/space-config.service.d.ts +23 -0
- package/dist/services/space-config.service.spec.d.ts +2 -0
- package/dist/services/trust-enforcement.d.ts +83 -0
- package/dist/services/trust-enforcement.spec.d.ts +2 -0
- package/dist/services/trust-validator.d.ts +43 -0
- package/dist/services/trust-validator.spec.d.ts +2 -0
- package/dist/tools/confirm-publish-moderation.spec.d.ts +8 -0
- package/dist/tools/confirm.d.ts +8 -1
- package/dist/tools/create-memory.d.ts +2 -1
- package/dist/tools/create-memory.spec.d.ts +10 -0
- package/dist/tools/create-relationship.d.ts +2 -1
- package/dist/tools/delete-memory.d.ts +2 -1
- package/dist/tools/delete-relationship.d.ts +2 -1
- package/dist/tools/deny.d.ts +2 -1
- package/dist/tools/find-similar.d.ts +2 -1
- package/dist/tools/get-preferences.d.ts +2 -1
- package/dist/tools/ghost-config.d.ts +27 -0
- package/dist/tools/ghost-config.spec.d.ts +2 -0
- package/dist/tools/moderate.d.ts +20 -0
- package/dist/tools/moderate.spec.d.ts +5 -0
- package/dist/tools/publish.d.ts +11 -3
- package/dist/tools/query-memory.d.ts +3 -1
- package/dist/tools/query-space.d.ts +4 -1
- package/dist/tools/retract.d.ts +29 -0
- package/dist/tools/revise.d.ts +45 -0
- package/dist/tools/revise.spec.d.ts +8 -0
- package/dist/tools/search-memory.d.ts +2 -1
- package/dist/tools/search-relationship.d.ts +2 -1
- package/dist/tools/search-space.d.ts +25 -5
- package/dist/tools/search-space.spec.d.ts +9 -0
- package/dist/tools/set-preference.d.ts +2 -1
- package/dist/tools/update-memory.d.ts +2 -1
- package/dist/tools/update-relationship.d.ts +2 -1
- package/dist/types/access-result.d.ts +48 -0
- package/dist/types/access-result.spec.d.ts +2 -0
- package/dist/types/auth.d.ts +46 -0
- package/dist/types/ghost-config.d.ts +36 -0
- package/dist/types/memory.d.ts +3 -1
- package/dist/types/preferences.d.ts +1 -1
- package/dist/utils/auth-helpers.d.ts +14 -0
- package/dist/utils/auth-helpers.spec.d.ts +2 -0
- package/dist/utils/test-data-generator.d.ts +124 -0
- package/dist/utils/test-data-generator.spec.d.ts +12 -0
- package/dist/v2-performance.e2e.d.ts +17 -0
- package/dist/v2-smoke.e2e.d.ts +14 -0
- package/dist/weaviate/client.d.ts +5 -8
- package/dist/weaviate/space-schema.d.ts +2 -2
- package/docs/performance/v2-benchmarks.md +80 -0
- package/jest.e2e.config.js +14 -3
- package/package.json +1 -1
- package/scripts/.collection-recreation-state.yaml +16 -0
- package/scripts/.gitkeep +5 -0
- package/scripts/README-collection-recreation.md +224 -0
- package/scripts/README.md +51 -0
- package/scripts/backup-collections.ts +543 -0
- package/scripts/delete-collection.ts +137 -0
- package/scripts/migrate-recreate-collections.ts +578 -0
- package/scripts/migrate-v1-to-v2.ts +1094 -0
- package/scripts/package-lock.json +1113 -0
- package/scripts/package.json +27 -0
- package/src/collections/composite-ids.ts +193 -0
- package/src/collections/core-infrastructure.spec.ts +353 -0
- package/src/collections/dot-notation.ts +212 -0
- package/src/collections/tracking-arrays.ts +298 -0
- package/src/constants/content-types.ts +20 -0
- package/src/schema/v2-collections-comments.spec.ts +141 -0
- package/src/schema/v2-collections.ts +433 -0
- package/src/server-factory.ts +89 -20
- package/src/server.ts +45 -17
- package/src/services/access-control.spec.ts +383 -0
- package/src/services/access-control.ts +291 -0
- package/src/services/credentials-provider.spec.ts +22 -0
- package/src/services/credentials-provider.ts +34 -0
- package/src/services/escalation.service.spec.ts +183 -0
- package/src/services/escalation.service.ts +150 -0
- package/src/services/ghost-config.service.spec.ts +339 -0
- package/src/services/ghost-config.service.ts +219 -0
- package/src/services/space-config.service.spec.ts +102 -0
- package/src/services/space-config.service.ts +79 -0
- package/src/services/trust-enforcement.spec.ts +309 -0
- package/src/services/trust-enforcement.ts +197 -0
- package/src/services/trust-validator.spec.ts +108 -0
- package/src/services/trust-validator.ts +105 -0
- package/src/tools/confirm-publish-moderation.spec.ts +240 -0
- package/src/tools/confirm.ts +869 -135
- package/src/tools/create-memory.spec.ts +126 -0
- package/src/tools/create-memory.ts +20 -27
- package/src/tools/create-relationship.ts +17 -8
- package/src/tools/delete-memory.ts +13 -6
- package/src/tools/delete-relationship.ts +15 -6
- package/src/tools/deny.ts +8 -1
- package/src/tools/find-similar.ts +21 -8
- package/src/tools/get-preferences.ts +10 -1
- package/src/tools/ghost-config.spec.ts +180 -0
- package/src/tools/ghost-config.ts +230 -0
- package/src/tools/moderate.spec.ts +277 -0
- package/src/tools/moderate.ts +219 -0
- package/src/tools/publish.ts +99 -41
- package/src/tools/query-memory.ts +28 -6
- package/src/tools/query-space.ts +39 -4
- package/src/tools/retract.ts +292 -0
- package/src/tools/revise.spec.ts +146 -0
- package/src/tools/revise.ts +283 -0
- package/src/tools/search-memory.ts +30 -7
- package/src/tools/search-relationship.ts +11 -2
- package/src/tools/search-space.spec.ts +341 -0
- package/src/tools/search-space.ts +323 -99
- package/src/tools/set-preference.ts +10 -1
- package/src/tools/update-memory.ts +16 -5
- package/src/tools/update-relationship.ts +10 -1
- package/src/types/access-result.spec.ts +193 -0
- package/src/types/access-result.ts +62 -0
- package/src/types/auth.ts +52 -0
- package/src/types/ghost-config.ts +46 -0
- package/src/types/memory.ts +9 -1
- package/src/types/preferences.ts +2 -2
- package/src/utils/auth-helpers.spec.ts +75 -0
- package/src/utils/auth-helpers.ts +25 -0
- package/src/utils/test-data-generator.spec.ts +317 -0
- package/src/utils/test-data-generator.ts +292 -0
- package/src/utils/weaviate-filters.ts +4 -4
- package/src/v2-performance.e2e.ts +173 -0
- package/src/v2-smoke.e2e.ts +401 -0
- package/src/weaviate/client.spec.ts +5 -5
- package/src/weaviate/client.ts +51 -36
- package/src/weaviate/schema.ts +11 -256
- package/src/weaviate/space-schema.spec.ts +24 -24
- package/src/weaviate/space-schema.ts +18 -6
package/src/weaviate/client.ts
CHANGED
|
@@ -104,26 +104,26 @@ export async function testWeaviateConnection(): Promise<boolean> {
|
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* Sanitize user_id for collection name
|
|
107
|
-
*
|
|
107
|
+
* @deprecated v2 uses literal userId — no sanitization needed. Kept for migration script only.
|
|
108
108
|
*/
|
|
109
109
|
export function sanitizeUserId(userId: string): string {
|
|
110
110
|
// Remove special characters, keep alphanumeric
|
|
111
111
|
let sanitized = userId.replace(/[^a-zA-Z0-9]/g, '_');
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
// If starts with number, prepend underscore
|
|
114
114
|
if (/^[0-9]/.test(sanitized)) {
|
|
115
115
|
sanitized = '_' + sanitized;
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
// Ensure starts with uppercase letter
|
|
119
119
|
return sanitized.charAt(0).toUpperCase() + sanitized.slice(1);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
|
-
* Get collection name for user's memories
|
|
123
|
+
* Get collection name for user's memories (v2 format)
|
|
124
124
|
*/
|
|
125
125
|
export function getMemoryCollectionName(userId: string): string {
|
|
126
|
-
return `
|
|
126
|
+
return `Memory_users_${userId}`;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
@@ -142,54 +142,67 @@ export function getAuditCollectionName(userId: string): string {
|
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* List of all memory properties to fetch
|
|
145
|
-
* Centralized to ensure consistency across all tools
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* List of all memory properties to fetch
|
|
149
|
-
* Matches the actual Weaviate schema properties exactly
|
|
145
|
+
* Centralized to ensure consistency across all tools.
|
|
146
|
+
* Includes both v2 canonical names and v1 compat names.
|
|
150
147
|
*/
|
|
151
148
|
export const ALL_MEMORY_PROPERTIES = [
|
|
152
149
|
// Core identity
|
|
153
150
|
'user_id',
|
|
154
151
|
'doc_type',
|
|
155
|
-
|
|
152
|
+
|
|
156
153
|
// Memory fields
|
|
157
154
|
'content',
|
|
155
|
+
'content_type', // v2 canonical
|
|
158
156
|
'title',
|
|
159
157
|
'summary',
|
|
160
|
-
'type',
|
|
161
|
-
|
|
158
|
+
'type', // v1 compat (v2: content_type)
|
|
159
|
+
|
|
162
160
|
// Scoring fields
|
|
163
161
|
'weight',
|
|
164
162
|
'base_weight',
|
|
165
|
-
'
|
|
163
|
+
'trust_score', // v2 canonical
|
|
164
|
+
'trust', // v1 compat (v2: trust_score)
|
|
166
165
|
'confidence',
|
|
167
166
|
'computed_weight',
|
|
168
|
-
|
|
169
|
-
// Location fields (
|
|
167
|
+
|
|
168
|
+
// Location fields (v2)
|
|
169
|
+
'location_name',
|
|
170
|
+
'location_lat', // v2 canonical
|
|
171
|
+
'location_lon', // v2 canonical
|
|
172
|
+
// Location fields (v1 compat)
|
|
170
173
|
'location_gps_lat',
|
|
171
174
|
'location_gps_lng',
|
|
172
175
|
'location_address',
|
|
173
176
|
'location_city',
|
|
174
177
|
'location_country',
|
|
175
178
|
'location_source',
|
|
176
|
-
|
|
179
|
+
|
|
177
180
|
// Locale fields
|
|
178
181
|
'locale_language',
|
|
179
182
|
'locale_timezone',
|
|
180
|
-
|
|
181
|
-
// Context fields
|
|
183
|
+
|
|
184
|
+
// Context fields
|
|
182
185
|
'context_conversation_id',
|
|
183
186
|
'context_summary',
|
|
184
187
|
'context_timestamp',
|
|
185
|
-
|
|
186
|
-
|
|
188
|
+
'context_app',
|
|
189
|
+
'context_url',
|
|
190
|
+
|
|
191
|
+
// Relationships (v2)
|
|
192
|
+
'relationship_ids', // v2 canonical
|
|
193
|
+
'related_memory_ids', // v2 canonical
|
|
194
|
+
// Relationships (v1 compat)
|
|
187
195
|
'relationships',
|
|
188
|
-
|
|
196
|
+
'memory_ids',
|
|
197
|
+
// Common relationship fields
|
|
198
|
+
'relationship_type',
|
|
199
|
+
'observation',
|
|
200
|
+
'strength',
|
|
201
|
+
|
|
189
202
|
// Access tracking
|
|
190
203
|
'access_count',
|
|
191
204
|
'last_accessed_at',
|
|
192
|
-
|
|
205
|
+
|
|
193
206
|
// Metadata
|
|
194
207
|
'tags',
|
|
195
208
|
'references',
|
|
@@ -197,28 +210,30 @@ export const ALL_MEMORY_PROPERTIES = [
|
|
|
197
210
|
'updated_at',
|
|
198
211
|
'version',
|
|
199
212
|
'template_id',
|
|
200
|
-
|
|
201
|
-
//
|
|
202
|
-
'
|
|
203
|
-
'
|
|
204
|
-
|
|
205
|
-
'strength',
|
|
206
|
-
|
|
213
|
+
|
|
214
|
+
// Tracking arrays (v2)
|
|
215
|
+
'space_ids',
|
|
216
|
+
'group_ids',
|
|
217
|
+
|
|
207
218
|
// Comment/threading fields
|
|
208
219
|
'parent_id',
|
|
209
220
|
'thread_root_id',
|
|
210
221
|
'moderation_flags',
|
|
211
|
-
|
|
212
|
-
// Space/publishing fields
|
|
213
|
-
'spaces',
|
|
214
|
-
'space_id',
|
|
222
|
+
|
|
223
|
+
// Space/publishing fields
|
|
224
|
+
'spaces', // legacy
|
|
225
|
+
'space_id', // legacy
|
|
215
226
|
'author_id',
|
|
216
227
|
'ghost_id',
|
|
217
228
|
'attribution',
|
|
218
229
|
'published_at',
|
|
219
230
|
'discovery_count',
|
|
220
|
-
'space_memory_id',
|
|
221
|
-
|
|
231
|
+
'space_memory_id', // legacy
|
|
232
|
+
'original_memory_id',
|
|
233
|
+
'revised_at',
|
|
234
|
+
'revision_count',
|
|
235
|
+
'revision_history',
|
|
236
|
+
|
|
222
237
|
// Soft delete fields
|
|
223
238
|
'deleted_at',
|
|
224
239
|
'deleted_by',
|
package/src/weaviate/schema.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import weaviate, { WeaviateClient } from 'weaviate-client';
|
|
7
|
-
import { getWeaviateClient
|
|
7
|
+
import { getWeaviateClient } from './client.js';
|
|
8
8
|
import { config } from '../config.js';
|
|
9
9
|
import { logger } from '../utils/logger.js';
|
|
10
|
+
import { createUserCollectionSchema } from '../schema/v2-collections.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Create Memory collection schema for a user
|
|
@@ -21,7 +22,7 @@ import { logger } from '../utils/logger.js';
|
|
|
21
22
|
*/
|
|
22
23
|
export async function createMemoryCollection(userId: string): Promise<void> {
|
|
23
24
|
const client = getWeaviateClient();
|
|
24
|
-
const collectionName = `
|
|
25
|
+
const collectionName = `Memory_users_${userId}`;
|
|
25
26
|
|
|
26
27
|
// Check if collection already exists
|
|
27
28
|
const exists = await client.collections.exists(collectionName);
|
|
@@ -38,255 +39,9 @@ export async function createMemoryCollection(userId: string): Promise<void> {
|
|
|
38
39
|
collectionName,
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
// Create collection
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Vectorizer configuration
|
|
46
|
-
vectorizers: weaviate.configure.vectorizer.text2VecOpenAI({
|
|
47
|
-
model: 'text-embedding-3-small',
|
|
48
|
-
// Vectorize content, title, summary, and observation for semantic search
|
|
49
|
-
// Note: title and summary are optional fields
|
|
50
|
-
sourceProperties: ['content', 'title', 'summary', 'observation'],
|
|
51
|
-
}),
|
|
52
|
-
|
|
53
|
-
properties: [
|
|
54
|
-
// Discriminator
|
|
55
|
-
{
|
|
56
|
-
name: 'doc_type',
|
|
57
|
-
dataType: 'text' as any,
|
|
58
|
-
description: 'Document type: "memory" or "relationship"',
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// Core identity
|
|
62
|
-
{
|
|
63
|
-
name: 'user_id',
|
|
64
|
-
dataType: 'text' as any,
|
|
65
|
-
description: 'User who owns this document',
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
// Memory fields
|
|
69
|
-
{
|
|
70
|
-
name: 'content',
|
|
71
|
-
dataType: 'text' as any,
|
|
72
|
-
description: 'Main memory content (vectorized)',
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
name: 'title',
|
|
76
|
-
dataType: 'text' as any,
|
|
77
|
-
description: 'Optional short title',
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
name: 'summary',
|
|
81
|
-
dataType: 'text' as any,
|
|
82
|
-
description: 'Optional brief summary',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'type',
|
|
86
|
-
dataType: 'text' as any,
|
|
87
|
-
description: 'Content type (note, event, person, etc.)',
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
// Scoring fields
|
|
91
|
-
{
|
|
92
|
-
name: 'weight',
|
|
93
|
-
dataType: 'number' as any,
|
|
94
|
-
description: 'Significance/priority (0-1)',
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'trust',
|
|
98
|
-
dataType: 'number' as any,
|
|
99
|
-
description: 'Access control level (0-1)',
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
name: 'confidence',
|
|
103
|
-
dataType: 'number' as any,
|
|
104
|
-
description: 'System confidence in accuracy (0-1)',
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
// Location fields (flattened for Weaviate)
|
|
108
|
-
{
|
|
109
|
-
name: 'location_gps_lat',
|
|
110
|
-
dataType: 'number' as any,
|
|
111
|
-
description: 'GPS latitude',
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
name: 'location_gps_lng',
|
|
115
|
-
dataType: 'number' as any,
|
|
116
|
-
description: 'GPS longitude',
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
name: 'location_address',
|
|
120
|
-
dataType: 'text' as any,
|
|
121
|
-
description: 'Formatted address',
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'location_city',
|
|
125
|
-
dataType: 'text' as any,
|
|
126
|
-
description: 'City name',
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: 'location_country',
|
|
130
|
-
dataType: 'text' as any,
|
|
131
|
-
description: 'Country name',
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
name: 'location_source',
|
|
135
|
-
dataType: 'text' as any,
|
|
136
|
-
description: 'Location source (gps, ip, manual, etc.)',
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
// Locale fields
|
|
140
|
-
{
|
|
141
|
-
name: 'locale_language',
|
|
142
|
-
dataType: 'text' as any,
|
|
143
|
-
description: 'Language code (e.g., en, es, fr)',
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'locale_timezone',
|
|
147
|
-
dataType: 'text' as any,
|
|
148
|
-
description: 'Timezone (e.g., America/Los_Angeles)',
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
// Context fields
|
|
152
|
-
{
|
|
153
|
-
name: 'context_conversation_id',
|
|
154
|
-
dataType: 'text' as any,
|
|
155
|
-
description: 'Conversation ID',
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
name: 'context_summary',
|
|
159
|
-
dataType: 'text' as any,
|
|
160
|
-
description: 'Brief context summary',
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: 'context_timestamp',
|
|
164
|
-
dataType: 'date' as any,
|
|
165
|
-
description: 'Context timestamp',
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
// Relationships
|
|
169
|
-
{
|
|
170
|
-
name: 'relationships',
|
|
171
|
-
dataType: 'text[]' as any,
|
|
172
|
-
description: 'Array of relationship IDs',
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
// Access tracking
|
|
176
|
-
{
|
|
177
|
-
name: 'access_count',
|
|
178
|
-
dataType: 'number' as any,
|
|
179
|
-
description: 'Total times accessed',
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
name: 'last_accessed_at',
|
|
183
|
-
dataType: 'date' as any,
|
|
184
|
-
description: 'Most recent access timestamp',
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
// Metadata
|
|
188
|
-
{
|
|
189
|
-
name: 'tags',
|
|
190
|
-
dataType: 'text[]' as any,
|
|
191
|
-
description: 'Tags for organization',
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
name: 'references',
|
|
195
|
-
dataType: 'text[]' as any,
|
|
196
|
-
description: 'Source URLs',
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: 'created_at',
|
|
200
|
-
dataType: 'date' as any,
|
|
201
|
-
description: 'Creation timestamp',
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: 'updated_at',
|
|
205
|
-
dataType: 'date' as any,
|
|
206
|
-
description: 'Last update timestamp',
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
name: 'version',
|
|
210
|
-
dataType: 'number' as any,
|
|
211
|
-
description: 'Version number',
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
// Template fields
|
|
215
|
-
{
|
|
216
|
-
name: 'template_id',
|
|
217
|
-
dataType: 'text' as any,
|
|
218
|
-
description: 'Template ID if using template',
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
// Relationship-specific fields
|
|
222
|
-
{
|
|
223
|
-
name: 'memory_ids',
|
|
224
|
-
dataType: 'text[]' as any,
|
|
225
|
-
description: 'Connected memory IDs (for relationships)',
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
name: 'relationship_type',
|
|
229
|
-
dataType: 'text' as any,
|
|
230
|
-
description: 'Relationship type (for relationships)',
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: 'observation',
|
|
234
|
-
dataType: 'text' as any,
|
|
235
|
-
description: 'Relationship observation (vectorized)',
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
name: 'strength',
|
|
239
|
-
dataType: 'number' as any,
|
|
240
|
-
description: 'Relationship strength (0-1)',
|
|
241
|
-
},
|
|
242
|
-
|
|
243
|
-
// Computed fields
|
|
244
|
-
{
|
|
245
|
-
name: 'base_weight',
|
|
246
|
-
dataType: 'number' as any,
|
|
247
|
-
description: 'User-specified weight',
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
name: 'computed_weight',
|
|
251
|
-
dataType: 'number' as any,
|
|
252
|
-
description: 'Calculated effective weight',
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
// Comment/threading fields (for threaded discussions in shared spaces)
|
|
256
|
-
{
|
|
257
|
-
name: 'parent_id',
|
|
258
|
-
dataType: 'text' as any,
|
|
259
|
-
description: 'ID of parent memory or comment (for threading)',
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
name: 'thread_root_id',
|
|
263
|
-
dataType: 'text' as any,
|
|
264
|
-
description: 'Root memory ID for fetching entire thread',
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
name: 'moderation_flags',
|
|
268
|
-
dataType: 'text[]' as any,
|
|
269
|
-
description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")',
|
|
270
|
-
},
|
|
271
|
-
|
|
272
|
-
// Soft delete fields
|
|
273
|
-
{
|
|
274
|
-
name: 'deleted_at',
|
|
275
|
-
dataType: 'date' as any,
|
|
276
|
-
description: 'Timestamp when memory was soft-deleted (null = not deleted)',
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
name: 'deleted_by',
|
|
280
|
-
dataType: 'text' as any,
|
|
281
|
-
description: 'User ID who deleted the memory',
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
name: 'deletion_reason',
|
|
285
|
-
dataType: 'text' as any,
|
|
286
|
-
description: 'Optional reason for deletion',
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
});
|
|
42
|
+
// Create collection using v2 schema
|
|
43
|
+
const schema = createUserCollectionSchema(userId);
|
|
44
|
+
await client.collections.create(schema);
|
|
290
45
|
|
|
291
46
|
logger.info('Memory collection created successfully', {
|
|
292
47
|
module: 'weaviate-schema',
|
|
@@ -299,10 +54,10 @@ export async function createMemoryCollection(userId: string): Promise<void> {
|
|
|
299
54
|
*/
|
|
300
55
|
export async function ensureMemoryCollection(userId: string): Promise<void> {
|
|
301
56
|
const client = getWeaviateClient();
|
|
302
|
-
const collectionName = `
|
|
57
|
+
const collectionName = `Memory_users_${userId}`;
|
|
303
58
|
|
|
304
59
|
const exists = await client.collections.exists(collectionName);
|
|
305
|
-
|
|
60
|
+
|
|
306
61
|
if (!exists) {
|
|
307
62
|
await createMemoryCollection(userId);
|
|
308
63
|
}
|
|
@@ -313,7 +68,7 @@ export async function ensureMemoryCollection(userId: string): Promise<void> {
|
|
|
313
68
|
*/
|
|
314
69
|
export function getMemoryCollection(userId: string) {
|
|
315
70
|
const client = getWeaviateClient();
|
|
316
|
-
const collectionName = `
|
|
71
|
+
const collectionName = `Memory_users_${userId}`;
|
|
317
72
|
return client.collections.get(collectionName);
|
|
318
73
|
}
|
|
319
74
|
|
|
@@ -322,10 +77,10 @@ export function getMemoryCollection(userId: string) {
|
|
|
322
77
|
*/
|
|
323
78
|
export async function deleteMemoryCollection(userId: string): Promise<void> {
|
|
324
79
|
const client = getWeaviateClient();
|
|
325
|
-
const collectionName = `
|
|
80
|
+
const collectionName = `Memory_users_${userId}`;
|
|
326
81
|
|
|
327
82
|
const exists = await client.collections.exists(collectionName);
|
|
328
|
-
|
|
83
|
+
|
|
329
84
|
if (exists) {
|
|
330
85
|
await client.collections.delete(collectionName);
|
|
331
86
|
logger.info('Memory collection deleted', {
|
|
@@ -119,10 +119,10 @@ describe('Space Schema Utilities', () => {
|
|
|
119
119
|
expect(createCall.vectorizers).toBeDefined();
|
|
120
120
|
expect(createCall.properties).toBeDefined();
|
|
121
121
|
expect(createCall.properties.length).toBeGreaterThan(20); // Should have many properties
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
// Check for space-specific properties
|
|
124
124
|
const propertyNames = createCall.properties.map((p: any) => p.name);
|
|
125
|
-
expect(propertyNames).toContain('spaces'); //
|
|
125
|
+
expect(propertyNames).toContain('spaces'); // legacy multi-space array field
|
|
126
126
|
expect(propertyNames).toContain('author_id');
|
|
127
127
|
expect(propertyNames).toContain('ghost_id');
|
|
128
128
|
expect(propertyNames).toContain('published_at');
|
|
@@ -135,9 +135,9 @@ describe('Space Schema Utilities', () => {
|
|
|
135
135
|
});
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
describe('Unified Public Collection', () => {
|
|
139
|
-
it('should create
|
|
140
|
-
const mockCollection = { name: '
|
|
138
|
+
describe('Unified Public Collection (v2: Memory_spaces_public)', () => {
|
|
139
|
+
it('should create Memory_spaces_public collection', async () => {
|
|
140
|
+
const mockCollection = { name: 'Memory_spaces_public' };
|
|
141
141
|
(mockWeaviateClient.collections.exists as jest.Mock).mockResolvedValue(false);
|
|
142
142
|
(mockWeaviateClient.collections.create as jest.Mock).mockResolvedValue(undefined);
|
|
143
143
|
(mockWeaviateClient.collections.get as jest.Mock).mockReturnValue(mockCollection);
|
|
@@ -145,25 +145,25 @@ describe('Space Schema Utilities', () => {
|
|
|
145
145
|
const result = await ensurePublicCollection(mockWeaviateClient);
|
|
146
146
|
|
|
147
147
|
expect(result).toBe(mockCollection);
|
|
148
|
-
expect(mockWeaviateClient.collections.exists).toHaveBeenCalledWith('
|
|
148
|
+
expect(mockWeaviateClient.collections.exists).toHaveBeenCalledWith('Memory_spaces_public');
|
|
149
149
|
expect(mockWeaviateClient.collections.create).toHaveBeenCalled();
|
|
150
|
-
expect(mockWeaviateClient.collections.get).toHaveBeenCalledWith('
|
|
150
|
+
expect(mockWeaviateClient.collections.get).toHaveBeenCalledWith('Memory_spaces_public');
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
it('should return existing
|
|
154
|
-
const mockCollection = { name: '
|
|
153
|
+
it('should return existing Memory_spaces_public if it exists', async () => {
|
|
154
|
+
const mockCollection = { name: 'Memory_spaces_public' };
|
|
155
155
|
(mockWeaviateClient.collections.exists as jest.Mock).mockResolvedValue(true);
|
|
156
156
|
(mockWeaviateClient.collections.get as jest.Mock).mockReturnValue(mockCollection);
|
|
157
157
|
|
|
158
158
|
const result = await ensurePublicCollection(mockWeaviateClient);
|
|
159
159
|
|
|
160
160
|
expect(result).toBe(mockCollection);
|
|
161
|
-
expect(mockWeaviateClient.collections.exists).toHaveBeenCalledWith('
|
|
162
|
-
expect(mockWeaviateClient.collections.get).toHaveBeenCalledWith('
|
|
161
|
+
expect(mockWeaviateClient.collections.exists).toHaveBeenCalledWith('Memory_spaces_public');
|
|
162
|
+
expect(mockWeaviateClient.collections.get).toHaveBeenCalledWith('Memory_spaces_public');
|
|
163
163
|
expect(mockWeaviateClient.collections.create).not.toHaveBeenCalled();
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
it('should
|
|
166
|
+
it('should use v2 schema with space_ids array field', async () => {
|
|
167
167
|
(mockWeaviateClient.collections.exists as jest.Mock).mockResolvedValue(false);
|
|
168
168
|
(mockWeaviateClient.collections.create as jest.Mock).mockResolvedValue(undefined);
|
|
169
169
|
(mockWeaviateClient.collections.get as jest.Mock).mockReturnValue({});
|
|
@@ -171,19 +171,19 @@ describe('Space Schema Utilities', () => {
|
|
|
171
171
|
await ensurePublicCollection(mockWeaviateClient);
|
|
172
172
|
|
|
173
173
|
const createCall = (mockWeaviateClient.collections.create as jest.Mock).mock.calls[0][0];
|
|
174
|
+
expect(createCall.name).toBe('Memory_spaces_public');
|
|
175
|
+
|
|
174
176
|
const propertyNames = createCall.properties.map((p: any) => p.name);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
expect(propertyNames).toContain('
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
it('should verify PUBLIC_COLLECTION_NAME constant', () => {
|
|
186
|
-
expect(PUBLIC_COLLECTION_NAME).toBe('Memory_public');
|
|
177
|
+
// v2 tracking arrays
|
|
178
|
+
expect(propertyNames).toContain('space_ids');
|
|
179
|
+
expect(propertyNames).toContain('group_ids');
|
|
180
|
+
// v2 revision fields
|
|
181
|
+
expect(propertyNames).toContain('revision_count');
|
|
182
|
+
expect(propertyNames).toContain('revised_at');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('should verify PUBLIC_COLLECTION_NAME constant is v2 format', () => {
|
|
186
|
+
expect(PUBLIC_COLLECTION_NAME).toBe('Memory_spaces_public');
|
|
187
187
|
});
|
|
188
188
|
});
|
|
189
189
|
});
|
|
@@ -9,11 +9,12 @@ import weaviate, { type WeaviateClient, type Collection } from 'weaviate-client'
|
|
|
9
9
|
import { config } from '../config.js';
|
|
10
10
|
import { SUPPORTED_SPACES, type SpaceId } from '../types/space-memory.js';
|
|
11
11
|
import { logger } from '../utils/logger.js';
|
|
12
|
+
import { createSpaceCollectionSchema } from '../schema/v2-collections.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
* Unified public collection name for all public spaces
|
|
15
|
+
* Unified public collection name for all public spaces (v2)
|
|
15
16
|
*/
|
|
16
|
-
export const PUBLIC_COLLECTION_NAME = '
|
|
17
|
+
export const PUBLIC_COLLECTION_NAME = 'Memory_spaces_public';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Get collection name for a space
|
|
@@ -102,6 +103,12 @@ async function createSpaceCollection(
|
|
|
102
103
|
sourceProperties: ['content', 'title', 'summary', 'observation'],
|
|
103
104
|
}),
|
|
104
105
|
|
|
106
|
+
// Inverted index configuration
|
|
107
|
+
// indexNullState: true is required for filtering on null values (e.g., deleted_at IS NULL)
|
|
108
|
+
invertedIndex: weaviate.configure.invertedIndex({
|
|
109
|
+
indexNullState: true,
|
|
110
|
+
}),
|
|
111
|
+
|
|
105
112
|
properties: [
|
|
106
113
|
// Discriminator
|
|
107
114
|
{
|
|
@@ -398,11 +405,16 @@ export async function ensurePublicCollection(
|
|
|
398
405
|
|
|
399
406
|
// Check if collection exists
|
|
400
407
|
const exists = await client.collections.exists(collectionName);
|
|
401
|
-
|
|
408
|
+
|
|
402
409
|
if (!exists) {
|
|
403
|
-
// Create
|
|
404
|
-
|
|
405
|
-
await
|
|
410
|
+
// Create using v2 schema
|
|
411
|
+
const schema = createSpaceCollectionSchema();
|
|
412
|
+
await client.collections.create(schema);
|
|
413
|
+
|
|
414
|
+
logger.info('Public space collection created', {
|
|
415
|
+
module: 'weaviate-space-schema',
|
|
416
|
+
collectionName,
|
|
417
|
+
});
|
|
406
418
|
}
|
|
407
419
|
|
|
408
420
|
return client.collections.get(collectionName);
|