@prmichaelsen/remember-mcp 3.16.0 → 3.16.2
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/.github/workflows/publish.yml +55 -0
- package/dist/server-factory.js +179 -3
- package/dist/server.js +179 -3
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [mainline]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 2
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: 20
|
|
20
|
+
registry-url: https://registry.npmjs.org
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm ci
|
|
24
|
+
|
|
25
|
+
- name: Build
|
|
26
|
+
run: npm run build
|
|
27
|
+
|
|
28
|
+
- name: Test
|
|
29
|
+
run: npm test
|
|
30
|
+
|
|
31
|
+
- name: Check if version changed
|
|
32
|
+
id: version
|
|
33
|
+
run: |
|
|
34
|
+
CURRENT=$(node -p "require('./package.json').version")
|
|
35
|
+
PREVIOUS=$(git show HEAD~1:package.json 2>/dev/null | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')).version" 2>/dev/null || echo "")
|
|
36
|
+
if [ "$CURRENT" != "$PREVIOUS" ]; then
|
|
37
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
38
|
+
echo "version=$CURRENT" >> "$GITHUB_OUTPUT"
|
|
39
|
+
else
|
|
40
|
+
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
- name: Publish
|
|
44
|
+
if: steps.version.outputs.changed == 'true'
|
|
45
|
+
run: npm publish --access public
|
|
46
|
+
env:
|
|
47
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
48
|
+
|
|
49
|
+
- name: Summary
|
|
50
|
+
if: steps.version.outputs.changed == 'true'
|
|
51
|
+
run: echo "Published @prmichaelsen/remember-mcp@${{ steps.version.outputs.version }} to npm"
|
|
52
|
+
|
|
53
|
+
- name: Skip
|
|
54
|
+
if: steps.version.outputs.changed != 'true'
|
|
55
|
+
run: echo "Version unchanged, skipping publish"
|
package/dist/server-factory.js
CHANGED
|
@@ -1931,7 +1931,13 @@ var COMMON_MEMORY_PROPERTIES = [
|
|
|
1931
1931
|
{ name: "total_significance", dataType: configure.dataType.NUMBER },
|
|
1932
1932
|
// REM metadata
|
|
1933
1933
|
{ name: "rem_touched_at", dataType: configure.dataType.TEXT },
|
|
1934
|
-
{ name: "rem_visits", dataType: configure.dataType.INT }
|
|
1934
|
+
{ name: "rem_visits", dataType: configure.dataType.INT },
|
|
1935
|
+
// Curation scoring (M36)
|
|
1936
|
+
{ name: "curated_score", dataType: configure.dataType.NUMBER },
|
|
1937
|
+
{ name: "editorial_score", dataType: configure.dataType.NUMBER },
|
|
1938
|
+
{ name: "click_count", dataType: configure.dataType.INT },
|
|
1939
|
+
{ name: "share_count", dataType: configure.dataType.INT },
|
|
1940
|
+
{ name: "comment_count", dataType: configure.dataType.INT }
|
|
1935
1941
|
];
|
|
1936
1942
|
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
1937
1943
|
// Publication metadata
|
|
@@ -2582,7 +2588,13 @@ var ALL_MEMORY_PROPERTIES = [
|
|
|
2582
2588
|
"functional_significance",
|
|
2583
2589
|
"total_significance",
|
|
2584
2590
|
"rem_touched_at",
|
|
2585
|
-
"rem_visits"
|
|
2591
|
+
"rem_visits",
|
|
2592
|
+
// Curation scoring (M36)
|
|
2593
|
+
"curated_score",
|
|
2594
|
+
"editorial_score",
|
|
2595
|
+
"click_count",
|
|
2596
|
+
"share_count",
|
|
2597
|
+
"comment_count"
|
|
2586
2598
|
];
|
|
2587
2599
|
async function fetchMemoryWithAllProperties(collection, memoryId) {
|
|
2588
2600
|
try {
|
|
@@ -3358,6 +3370,99 @@ var MemoryService = class {
|
|
|
3358
3370
|
total_pool_size: totalPoolSize
|
|
3359
3371
|
};
|
|
3360
3372
|
}
|
|
3373
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
3374
|
+
async byCurated(input) {
|
|
3375
|
+
const limit = input.limit ?? 50;
|
|
3376
|
+
const offset = input.offset ?? 0;
|
|
3377
|
+
const direction = input.direction ?? "desc";
|
|
3378
|
+
const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
|
|
3379
|
+
const ghostFilters = [];
|
|
3380
|
+
if (input.ghost_context) {
|
|
3381
|
+
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
3382
|
+
}
|
|
3383
|
+
if (!input.ghost_context?.include_ghost_content && !input.filters?.types?.includes("ghost")) {
|
|
3384
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3385
|
+
}
|
|
3386
|
+
if (!input.filters?.types?.includes("rem")) {
|
|
3387
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3388
|
+
}
|
|
3389
|
+
const hasQuery = input.query?.trim();
|
|
3390
|
+
const fetchLimit = (limit + offset) * 2;
|
|
3391
|
+
const executeScoredQuery = async (useDeletedFilter) => {
|
|
3392
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3393
|
+
const scoredFilter = this.collection.filter.byProperty("curated_score").greaterThan(0);
|
|
3394
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, scoredFilter, ...ghostFilters].filter((f) => f !== null));
|
|
3395
|
+
if (hasQuery) {
|
|
3396
|
+
const queryOptions2 = {
|
|
3397
|
+
limit: fetchLimit,
|
|
3398
|
+
alpha: 0.7,
|
|
3399
|
+
query: hasQuery
|
|
3400
|
+
};
|
|
3401
|
+
if (combined)
|
|
3402
|
+
queryOptions2.filters = combined;
|
|
3403
|
+
return this.collection.query.hybrid(hasQuery, queryOptions2);
|
|
3404
|
+
}
|
|
3405
|
+
const queryOptions = {
|
|
3406
|
+
limit: fetchLimit,
|
|
3407
|
+
sort: this.collection.sort.byProperty("curated_score", direction === "asc")
|
|
3408
|
+
};
|
|
3409
|
+
if (combined)
|
|
3410
|
+
queryOptions.filters = combined;
|
|
3411
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3412
|
+
};
|
|
3413
|
+
const executeUnscoredQuery = async (useDeletedFilter) => {
|
|
3414
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3415
|
+
const unscoredFilters = [];
|
|
3416
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
|
|
3417
|
+
const queryOptions = {
|
|
3418
|
+
limit: Math.ceil(fetchLimit / 4),
|
|
3419
|
+
sort: this.collection.sort.byProperty("created_at", false)
|
|
3420
|
+
// newest first
|
|
3421
|
+
};
|
|
3422
|
+
if (combined)
|
|
3423
|
+
queryOptions.filters = combined;
|
|
3424
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3425
|
+
};
|
|
3426
|
+
const scoredResults = await this.retryWithoutDeletedFilter(executeScoredQuery);
|
|
3427
|
+
const unscoredResults = await this.retryWithoutDeletedFilter(executeUnscoredQuery);
|
|
3428
|
+
const scored = [];
|
|
3429
|
+
for (const obj of scoredResults.objects) {
|
|
3430
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3431
|
+
if (doc.doc_type === "memory" && doc.curated_score > 0) {
|
|
3432
|
+
scored.push(doc);
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
if (hasQuery) {
|
|
3436
|
+
scored.sort((a, b) => {
|
|
3437
|
+
const aScore = a.curated_score ?? 0;
|
|
3438
|
+
const bScore = b.curated_score ?? 0;
|
|
3439
|
+
return direction === "asc" ? aScore - bScore : bScore - aScore;
|
|
3440
|
+
});
|
|
3441
|
+
}
|
|
3442
|
+
const unscored = [];
|
|
3443
|
+
for (const obj of unscoredResults.objects) {
|
|
3444
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3445
|
+
if (doc.doc_type === "memory" && !doc.curated_score) {
|
|
3446
|
+
unscored.push(doc);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
const interleaved = interleaveDiscovery({
|
|
3450
|
+
rated: scored,
|
|
3451
|
+
discovery: unscored,
|
|
3452
|
+
offset,
|
|
3453
|
+
limit
|
|
3454
|
+
});
|
|
3455
|
+
const memories = interleaved.map((item) => ({
|
|
3456
|
+
...item.item,
|
|
3457
|
+
...item.is_discovery ? { is_discovery: true } : {}
|
|
3458
|
+
}));
|
|
3459
|
+
return {
|
|
3460
|
+
memories,
|
|
3461
|
+
total: memories.length,
|
|
3462
|
+
offset,
|
|
3463
|
+
limit
|
|
3464
|
+
};
|
|
3465
|
+
}
|
|
3361
3466
|
// ── Find Similar (vector) ──────────────────────────────────────────
|
|
3362
3467
|
async findSimilar(input) {
|
|
3363
3468
|
if (!input.memory_id && !input.text)
|
|
@@ -3374,6 +3479,7 @@ var MemoryService = class {
|
|
|
3374
3479
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3375
3480
|
}
|
|
3376
3481
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3482
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("comment"));
|
|
3377
3483
|
let memoryObj = null;
|
|
3378
3484
|
if (input.memory_id) {
|
|
3379
3485
|
memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
|
|
@@ -3565,6 +3671,28 @@ var MemoryService = class {
|
|
|
3565
3671
|
orphaned_relationship_ids: orphanedIds
|
|
3566
3672
|
};
|
|
3567
3673
|
}
|
|
3674
|
+
// ── Engagement Counters ───────────────────────────────────────────
|
|
3675
|
+
async incrementClick(memoryId) {
|
|
3676
|
+
await this.incrementCounter(memoryId, "click_count");
|
|
3677
|
+
}
|
|
3678
|
+
async incrementShare(memoryId) {
|
|
3679
|
+
await this.incrementCounter(memoryId, "share_count");
|
|
3680
|
+
}
|
|
3681
|
+
async incrementComment(memoryId) {
|
|
3682
|
+
await this.incrementCounter(memoryId, "comment_count");
|
|
3683
|
+
}
|
|
3684
|
+
async incrementCounter(memoryId, field) {
|
|
3685
|
+
const existing = await this.collection.query.fetchObjectById(memoryId, {
|
|
3686
|
+
returnProperties: [field]
|
|
3687
|
+
});
|
|
3688
|
+
if (!existing)
|
|
3689
|
+
throw new Error(`Memory not found: ${memoryId}`);
|
|
3690
|
+
const current = existing.properties?.[field] ?? 0;
|
|
3691
|
+
await this.collection.data.update({
|
|
3692
|
+
id: memoryId,
|
|
3693
|
+
properties: { [field]: current + 1 }
|
|
3694
|
+
});
|
|
3695
|
+
}
|
|
3568
3696
|
};
|
|
3569
3697
|
|
|
3570
3698
|
// node_modules/@prmichaelsen/remember-core/dist/services/relationship.service.js
|
|
@@ -5006,6 +5134,42 @@ var SpaceService = class {
|
|
|
5006
5134
|
});
|
|
5007
5135
|
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, results, total_pool_size: totalPoolSize };
|
|
5008
5136
|
}
|
|
5137
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
5138
|
+
async byCurated(input, authContext) {
|
|
5139
|
+
const spaces = input.spaces || [];
|
|
5140
|
+
const groups = input.groups || [];
|
|
5141
|
+
const limit = input.limit ?? 50;
|
|
5142
|
+
const offset = input.offset ?? 0;
|
|
5143
|
+
const direction = input.direction ?? "desc";
|
|
5144
|
+
this.validateSpaceGroupInput(spaces, groups, input.moderation_filter || "approved", authContext);
|
|
5145
|
+
const fetchLimit = (limit + offset) * 2;
|
|
5146
|
+
const hasQuery = input.query?.trim();
|
|
5147
|
+
const { allResults, spacesSearched, groupsSearched } = await this.fetchAcrossCollections(input, spaces, groups, async (collection, baseFilters) => {
|
|
5148
|
+
const combined = baseFilters.length > 0 ? Filters4.and(...baseFilters) : void 0;
|
|
5149
|
+
if (hasQuery) {
|
|
5150
|
+
const opts2 = { limit: fetchLimit, alpha: 0.7, query: hasQuery };
|
|
5151
|
+
if (combined)
|
|
5152
|
+
opts2.filters = combined;
|
|
5153
|
+
return (await collection.query.hybrid(hasQuery, opts2)).objects;
|
|
5154
|
+
}
|
|
5155
|
+
const opts = {
|
|
5156
|
+
limit: fetchLimit,
|
|
5157
|
+
sort: collection.sort.byProperty("curated_score", direction === "asc")
|
|
5158
|
+
};
|
|
5159
|
+
if (combined)
|
|
5160
|
+
opts.filters = combined;
|
|
5161
|
+
return (await collection.query.fetchObjects(opts)).objects;
|
|
5162
|
+
});
|
|
5163
|
+
const deduped = dedupeBySourceId(allResults, input.dedupe);
|
|
5164
|
+
deduped.sort((a, b) => {
|
|
5165
|
+
const aVal = a.properties?.curated_score ?? 0;
|
|
5166
|
+
const bVal = b.properties?.curated_score ?? 0;
|
|
5167
|
+
return direction === "desc" ? bVal - aVal : aVal - bVal;
|
|
5168
|
+
});
|
|
5169
|
+
const paginated = deduped.slice(offset, offset + limit);
|
|
5170
|
+
const memories = paginated.filter((obj) => obj.properties?.doc_type === "memory").map((obj) => ({ id: obj.uuid, ...obj.properties }));
|
|
5171
|
+
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, memories, total: memories.length, offset, limit };
|
|
5172
|
+
}
|
|
5009
5173
|
// ── Private: Validate Space/Group Input ───────────────────────────
|
|
5010
5174
|
validateSpaceGroupInput(spaces, groups, moderationFilter, authContext) {
|
|
5011
5175
|
if (spaces.length > 0) {
|
|
@@ -5150,6 +5314,18 @@ var REM_STATE_COLLECTION = `${BASE}.rem_state`;
|
|
|
5150
5314
|
// node_modules/@prmichaelsen/remember-core/dist/services/rem.clustering.js
|
|
5151
5315
|
import { Filters as Filters5 } from "weaviate-client";
|
|
5152
5316
|
|
|
5317
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.service.js
|
|
5318
|
+
import { Filters as Filters9 } from "weaviate-client";
|
|
5319
|
+
|
|
5320
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/scoring-context.service.js
|
|
5321
|
+
import { Filters as Filters6 } from "weaviate-client";
|
|
5322
|
+
|
|
5323
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.pruning.js
|
|
5324
|
+
import { Filters as Filters7 } from "weaviate-client";
|
|
5325
|
+
|
|
5326
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.reconciliation.js
|
|
5327
|
+
import { Filters as Filters8 } from "weaviate-client";
|
|
5328
|
+
|
|
5153
5329
|
// node_modules/@prmichaelsen/remember-core/dist/services/classification.service.js
|
|
5154
5330
|
var GENRES = [
|
|
5155
5331
|
"short_story",
|
|
@@ -7437,7 +7613,7 @@ async function handleDeny(args, userId, authContext) {
|
|
|
7437
7613
|
}
|
|
7438
7614
|
|
|
7439
7615
|
// src/tools/search-space.ts
|
|
7440
|
-
import { Filters as
|
|
7616
|
+
import { Filters as Filters10 } from "weaviate-client";
|
|
7441
7617
|
var searchSpaceTool = {
|
|
7442
7618
|
name: "remember_search_space",
|
|
7443
7619
|
description: `Search shared spaces and/or groups to discover memories from other users.
|
package/dist/server.js
CHANGED
|
@@ -1935,7 +1935,13 @@ var COMMON_MEMORY_PROPERTIES = [
|
|
|
1935
1935
|
{ name: "total_significance", dataType: configure.dataType.NUMBER },
|
|
1936
1936
|
// REM metadata
|
|
1937
1937
|
{ name: "rem_touched_at", dataType: configure.dataType.TEXT },
|
|
1938
|
-
{ name: "rem_visits", dataType: configure.dataType.INT }
|
|
1938
|
+
{ name: "rem_visits", dataType: configure.dataType.INT },
|
|
1939
|
+
// Curation scoring (M36)
|
|
1940
|
+
{ name: "curated_score", dataType: configure.dataType.NUMBER },
|
|
1941
|
+
{ name: "editorial_score", dataType: configure.dataType.NUMBER },
|
|
1942
|
+
{ name: "click_count", dataType: configure.dataType.INT },
|
|
1943
|
+
{ name: "share_count", dataType: configure.dataType.INT },
|
|
1944
|
+
{ name: "comment_count", dataType: configure.dataType.INT }
|
|
1939
1945
|
];
|
|
1940
1946
|
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
1941
1947
|
// Publication metadata
|
|
@@ -2586,7 +2592,13 @@ var ALL_MEMORY_PROPERTIES = [
|
|
|
2586
2592
|
"functional_significance",
|
|
2587
2593
|
"total_significance",
|
|
2588
2594
|
"rem_touched_at",
|
|
2589
|
-
"rem_visits"
|
|
2595
|
+
"rem_visits",
|
|
2596
|
+
// Curation scoring (M36)
|
|
2597
|
+
"curated_score",
|
|
2598
|
+
"editorial_score",
|
|
2599
|
+
"click_count",
|
|
2600
|
+
"share_count",
|
|
2601
|
+
"comment_count"
|
|
2590
2602
|
];
|
|
2591
2603
|
async function fetchMemoryWithAllProperties(collection, memoryId) {
|
|
2592
2604
|
try {
|
|
@@ -3362,6 +3374,99 @@ var MemoryService = class {
|
|
|
3362
3374
|
total_pool_size: totalPoolSize
|
|
3363
3375
|
};
|
|
3364
3376
|
}
|
|
3377
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
3378
|
+
async byCurated(input) {
|
|
3379
|
+
const limit = input.limit ?? 50;
|
|
3380
|
+
const offset = input.offset ?? 0;
|
|
3381
|
+
const direction = input.direction ?? "desc";
|
|
3382
|
+
const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
|
|
3383
|
+
const ghostFilters = [];
|
|
3384
|
+
if (input.ghost_context) {
|
|
3385
|
+
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
3386
|
+
}
|
|
3387
|
+
if (!input.ghost_context?.include_ghost_content && !input.filters?.types?.includes("ghost")) {
|
|
3388
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3389
|
+
}
|
|
3390
|
+
if (!input.filters?.types?.includes("rem")) {
|
|
3391
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3392
|
+
}
|
|
3393
|
+
const hasQuery = input.query?.trim();
|
|
3394
|
+
const fetchLimit = (limit + offset) * 2;
|
|
3395
|
+
const executeScoredQuery = async (useDeletedFilter) => {
|
|
3396
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3397
|
+
const scoredFilter = this.collection.filter.byProperty("curated_score").greaterThan(0);
|
|
3398
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, scoredFilter, ...ghostFilters].filter((f) => f !== null));
|
|
3399
|
+
if (hasQuery) {
|
|
3400
|
+
const queryOptions2 = {
|
|
3401
|
+
limit: fetchLimit,
|
|
3402
|
+
alpha: 0.7,
|
|
3403
|
+
query: hasQuery
|
|
3404
|
+
};
|
|
3405
|
+
if (combined)
|
|
3406
|
+
queryOptions2.filters = combined;
|
|
3407
|
+
return this.collection.query.hybrid(hasQuery, queryOptions2);
|
|
3408
|
+
}
|
|
3409
|
+
const queryOptions = {
|
|
3410
|
+
limit: fetchLimit,
|
|
3411
|
+
sort: this.collection.sort.byProperty("curated_score", direction === "asc")
|
|
3412
|
+
};
|
|
3413
|
+
if (combined)
|
|
3414
|
+
queryOptions.filters = combined;
|
|
3415
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3416
|
+
};
|
|
3417
|
+
const executeUnscoredQuery = async (useDeletedFilter) => {
|
|
3418
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3419
|
+
const unscoredFilters = [];
|
|
3420
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
|
|
3421
|
+
const queryOptions = {
|
|
3422
|
+
limit: Math.ceil(fetchLimit / 4),
|
|
3423
|
+
sort: this.collection.sort.byProperty("created_at", false)
|
|
3424
|
+
// newest first
|
|
3425
|
+
};
|
|
3426
|
+
if (combined)
|
|
3427
|
+
queryOptions.filters = combined;
|
|
3428
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3429
|
+
};
|
|
3430
|
+
const scoredResults = await this.retryWithoutDeletedFilter(executeScoredQuery);
|
|
3431
|
+
const unscoredResults = await this.retryWithoutDeletedFilter(executeUnscoredQuery);
|
|
3432
|
+
const scored = [];
|
|
3433
|
+
for (const obj of scoredResults.objects) {
|
|
3434
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3435
|
+
if (doc.doc_type === "memory" && doc.curated_score > 0) {
|
|
3436
|
+
scored.push(doc);
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
if (hasQuery) {
|
|
3440
|
+
scored.sort((a, b) => {
|
|
3441
|
+
const aScore = a.curated_score ?? 0;
|
|
3442
|
+
const bScore = b.curated_score ?? 0;
|
|
3443
|
+
return direction === "asc" ? aScore - bScore : bScore - aScore;
|
|
3444
|
+
});
|
|
3445
|
+
}
|
|
3446
|
+
const unscored = [];
|
|
3447
|
+
for (const obj of unscoredResults.objects) {
|
|
3448
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3449
|
+
if (doc.doc_type === "memory" && !doc.curated_score) {
|
|
3450
|
+
unscored.push(doc);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
const interleaved = interleaveDiscovery({
|
|
3454
|
+
rated: scored,
|
|
3455
|
+
discovery: unscored,
|
|
3456
|
+
offset,
|
|
3457
|
+
limit
|
|
3458
|
+
});
|
|
3459
|
+
const memories = interleaved.map((item) => ({
|
|
3460
|
+
...item.item,
|
|
3461
|
+
...item.is_discovery ? { is_discovery: true } : {}
|
|
3462
|
+
}));
|
|
3463
|
+
return {
|
|
3464
|
+
memories,
|
|
3465
|
+
total: memories.length,
|
|
3466
|
+
offset,
|
|
3467
|
+
limit
|
|
3468
|
+
};
|
|
3469
|
+
}
|
|
3365
3470
|
// ── Find Similar (vector) ──────────────────────────────────────────
|
|
3366
3471
|
async findSimilar(input) {
|
|
3367
3472
|
if (!input.memory_id && !input.text)
|
|
@@ -3378,6 +3483,7 @@ var MemoryService = class {
|
|
|
3378
3483
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3379
3484
|
}
|
|
3380
3485
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3486
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("comment"));
|
|
3381
3487
|
let memoryObj = null;
|
|
3382
3488
|
if (input.memory_id) {
|
|
3383
3489
|
memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
|
|
@@ -3569,6 +3675,28 @@ var MemoryService = class {
|
|
|
3569
3675
|
orphaned_relationship_ids: orphanedIds
|
|
3570
3676
|
};
|
|
3571
3677
|
}
|
|
3678
|
+
// ── Engagement Counters ───────────────────────────────────────────
|
|
3679
|
+
async incrementClick(memoryId) {
|
|
3680
|
+
await this.incrementCounter(memoryId, "click_count");
|
|
3681
|
+
}
|
|
3682
|
+
async incrementShare(memoryId) {
|
|
3683
|
+
await this.incrementCounter(memoryId, "share_count");
|
|
3684
|
+
}
|
|
3685
|
+
async incrementComment(memoryId) {
|
|
3686
|
+
await this.incrementCounter(memoryId, "comment_count");
|
|
3687
|
+
}
|
|
3688
|
+
async incrementCounter(memoryId, field) {
|
|
3689
|
+
const existing = await this.collection.query.fetchObjectById(memoryId, {
|
|
3690
|
+
returnProperties: [field]
|
|
3691
|
+
});
|
|
3692
|
+
if (!existing)
|
|
3693
|
+
throw new Error(`Memory not found: ${memoryId}`);
|
|
3694
|
+
const current = existing.properties?.[field] ?? 0;
|
|
3695
|
+
await this.collection.data.update({
|
|
3696
|
+
id: memoryId,
|
|
3697
|
+
properties: { [field]: current + 1 }
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3572
3700
|
};
|
|
3573
3701
|
|
|
3574
3702
|
// node_modules/@prmichaelsen/remember-core/dist/services/relationship.service.js
|
|
@@ -5010,6 +5138,42 @@ var SpaceService = class {
|
|
|
5010
5138
|
});
|
|
5011
5139
|
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, results, total_pool_size: totalPoolSize };
|
|
5012
5140
|
}
|
|
5141
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
5142
|
+
async byCurated(input, authContext) {
|
|
5143
|
+
const spaces = input.spaces || [];
|
|
5144
|
+
const groups = input.groups || [];
|
|
5145
|
+
const limit = input.limit ?? 50;
|
|
5146
|
+
const offset = input.offset ?? 0;
|
|
5147
|
+
const direction = input.direction ?? "desc";
|
|
5148
|
+
this.validateSpaceGroupInput(spaces, groups, input.moderation_filter || "approved", authContext);
|
|
5149
|
+
const fetchLimit = (limit + offset) * 2;
|
|
5150
|
+
const hasQuery = input.query?.trim();
|
|
5151
|
+
const { allResults, spacesSearched, groupsSearched } = await this.fetchAcrossCollections(input, spaces, groups, async (collection, baseFilters) => {
|
|
5152
|
+
const combined = baseFilters.length > 0 ? Filters4.and(...baseFilters) : void 0;
|
|
5153
|
+
if (hasQuery) {
|
|
5154
|
+
const opts2 = { limit: fetchLimit, alpha: 0.7, query: hasQuery };
|
|
5155
|
+
if (combined)
|
|
5156
|
+
opts2.filters = combined;
|
|
5157
|
+
return (await collection.query.hybrid(hasQuery, opts2)).objects;
|
|
5158
|
+
}
|
|
5159
|
+
const opts = {
|
|
5160
|
+
limit: fetchLimit,
|
|
5161
|
+
sort: collection.sort.byProperty("curated_score", direction === "asc")
|
|
5162
|
+
};
|
|
5163
|
+
if (combined)
|
|
5164
|
+
opts.filters = combined;
|
|
5165
|
+
return (await collection.query.fetchObjects(opts)).objects;
|
|
5166
|
+
});
|
|
5167
|
+
const deduped = dedupeBySourceId(allResults, input.dedupe);
|
|
5168
|
+
deduped.sort((a, b) => {
|
|
5169
|
+
const aVal = a.properties?.curated_score ?? 0;
|
|
5170
|
+
const bVal = b.properties?.curated_score ?? 0;
|
|
5171
|
+
return direction === "desc" ? bVal - aVal : aVal - bVal;
|
|
5172
|
+
});
|
|
5173
|
+
const paginated = deduped.slice(offset, offset + limit);
|
|
5174
|
+
const memories = paginated.filter((obj) => obj.properties?.doc_type === "memory").map((obj) => ({ id: obj.uuid, ...obj.properties }));
|
|
5175
|
+
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, memories, total: memories.length, offset, limit };
|
|
5176
|
+
}
|
|
5013
5177
|
// ── Private: Validate Space/Group Input ───────────────────────────
|
|
5014
5178
|
validateSpaceGroupInput(spaces, groups, moderationFilter, authContext) {
|
|
5015
5179
|
if (spaces.length > 0) {
|
|
@@ -5154,6 +5318,18 @@ var REM_STATE_COLLECTION = `${BASE}.rem_state`;
|
|
|
5154
5318
|
// node_modules/@prmichaelsen/remember-core/dist/services/rem.clustering.js
|
|
5155
5319
|
import { Filters as Filters5 } from "weaviate-client";
|
|
5156
5320
|
|
|
5321
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.service.js
|
|
5322
|
+
import { Filters as Filters9 } from "weaviate-client";
|
|
5323
|
+
|
|
5324
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/scoring-context.service.js
|
|
5325
|
+
import { Filters as Filters6 } from "weaviate-client";
|
|
5326
|
+
|
|
5327
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.pruning.js
|
|
5328
|
+
import { Filters as Filters7 } from "weaviate-client";
|
|
5329
|
+
|
|
5330
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.reconciliation.js
|
|
5331
|
+
import { Filters as Filters8 } from "weaviate-client";
|
|
5332
|
+
|
|
5157
5333
|
// node_modules/@prmichaelsen/remember-core/dist/services/classification.service.js
|
|
5158
5334
|
var GENRES = [
|
|
5159
5335
|
"short_story",
|
|
@@ -7441,7 +7617,7 @@ async function handleDeny(args, userId, authContext) {
|
|
|
7441
7617
|
}
|
|
7442
7618
|
|
|
7443
7619
|
// src/tools/search-space.ts
|
|
7444
|
-
import { Filters as
|
|
7620
|
+
import { Filters as Filters10 } from "weaviate-client";
|
|
7445
7621
|
var searchSpaceTool = {
|
|
7446
7622
|
name: "remember_search_space",
|
|
7447
7623
|
description: `Search shared spaces and/or groups to discover memories from other users.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prmichaelsen/remember-mcp",
|
|
3
|
-
"version": "3.16.
|
|
3
|
+
"version": "3.16.2",
|
|
4
4
|
"description": "Multi-tenant memory system MCP server with vector search and relationships",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@google-cloud/vision": "^5.3.4",
|
|
52
52
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
53
53
|
"@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
|
|
54
|
-
"@prmichaelsen/remember-core": "^0.
|
|
54
|
+
"@prmichaelsen/remember-core": "^0.49.16",
|
|
55
55
|
"dotenv": "^16.4.5",
|
|
56
56
|
"uuid": "^13.0.0",
|
|
57
57
|
"weaviate-client": "^3.2.0"
|