@prmichaelsen/remember-mcp 3.15.0 → 3.15.1
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/server-factory.js +319 -214
- package/dist/server.js +319 -214
- package/package.json +2 -2
package/dist/server-factory.js
CHANGED
|
@@ -1726,6 +1726,9 @@ function canModerateAny(authContext) {
|
|
|
1726
1726
|
return authContext.credentials.group_memberships.some((m) => m.permissions.can_moderate);
|
|
1727
1727
|
}
|
|
1728
1728
|
|
|
1729
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
1730
|
+
import { configure } from "weaviate-client";
|
|
1731
|
+
|
|
1729
1732
|
// node_modules/@prmichaelsen/remember-core/dist/database/firestore/init.js
|
|
1730
1733
|
import { initializeApp as initializeApp2 } from "@prmichaelsen/firebase-admin-sdk-v8";
|
|
1731
1734
|
import { getDocument as getDocument2, setDocument as setDocument2, addDocument as addDocument2, updateDocument as updateDocument2, deleteDocument as deleteDocument2, queryDocuments as queryDocuments2, batchWrite as batchWrite2, FieldValue as FieldValue2, verifyIdToken as verifyIdToken2 } from "@prmichaelsen/firebase-admin-sdk-v8";
|
|
@@ -1758,6 +1761,310 @@ function getMemoryIndexPath() {
|
|
|
1758
1761
|
return `${BASE}.memory_index`;
|
|
1759
1762
|
}
|
|
1760
1763
|
|
|
1764
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/collection-registry.js
|
|
1765
|
+
async function registerCollection(entry) {
|
|
1766
|
+
const path = getCollectionRegistryPath();
|
|
1767
|
+
await setDocument2(path, entry.collection_name, entry);
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
1771
|
+
var collectionCache = /* @__PURE__ */ new Map();
|
|
1772
|
+
var COLLECTION_CACHE_TTL_MS = 6e4;
|
|
1773
|
+
function isCollectionCached(collectionName) {
|
|
1774
|
+
const expiresAt = collectionCache.get(collectionName);
|
|
1775
|
+
if (expiresAt !== void 0 && Date.now() < expiresAt)
|
|
1776
|
+
return true;
|
|
1777
|
+
collectionCache.delete(collectionName);
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
function cacheCollection(collectionName) {
|
|
1781
|
+
collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
|
|
1782
|
+
}
|
|
1783
|
+
var COMMON_MEMORY_PROPERTIES = [
|
|
1784
|
+
// Core content
|
|
1785
|
+
{ name: "content", dataType: configure.dataType.TEXT },
|
|
1786
|
+
{ name: "content_type", dataType: configure.dataType.TEXT },
|
|
1787
|
+
{ name: "title", dataType: configure.dataType.TEXT },
|
|
1788
|
+
{ name: "summary", dataType: configure.dataType.TEXT },
|
|
1789
|
+
{ name: "type", dataType: configure.dataType.TEXT },
|
|
1790
|
+
// v1 compat (v2: content_type)
|
|
1791
|
+
// Tracking arrays (v2 feature)
|
|
1792
|
+
{ name: "space_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1793
|
+
{ name: "group_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1794
|
+
// Metadata
|
|
1795
|
+
{ name: "created_at", dataType: configure.dataType.DATE },
|
|
1796
|
+
{ name: "updated_at", dataType: configure.dataType.DATE },
|
|
1797
|
+
{ name: "version", dataType: configure.dataType.INT },
|
|
1798
|
+
// User context
|
|
1799
|
+
{ name: "user_id", dataType: configure.dataType.TEXT },
|
|
1800
|
+
// Document type (memory, relationship, comment)
|
|
1801
|
+
{ name: "doc_type", dataType: configure.dataType.TEXT },
|
|
1802
|
+
// Memory-specific fields
|
|
1803
|
+
{ name: "tags", dataType: configure.dataType.TEXT_ARRAY },
|
|
1804
|
+
{ name: "weight", dataType: configure.dataType.NUMBER },
|
|
1805
|
+
{ name: "trust_score", dataType: configure.dataType.NUMBER },
|
|
1806
|
+
{ name: "trust", dataType: configure.dataType.NUMBER },
|
|
1807
|
+
// v1 compat (v2: trust_score)
|
|
1808
|
+
{ name: "base_weight", dataType: configure.dataType.NUMBER },
|
|
1809
|
+
{ name: "computed_weight", dataType: configure.dataType.NUMBER },
|
|
1810
|
+
{ name: "confidence", dataType: configure.dataType.NUMBER },
|
|
1811
|
+
{ name: "strength", dataType: configure.dataType.NUMBER },
|
|
1812
|
+
// Location data (v2 names)
|
|
1813
|
+
{ name: "location_name", dataType: configure.dataType.TEXT },
|
|
1814
|
+
{ name: "location_lat", dataType: configure.dataType.NUMBER },
|
|
1815
|
+
{ name: "location_lon", dataType: configure.dataType.NUMBER },
|
|
1816
|
+
// Location data (v1 compat)
|
|
1817
|
+
{ name: "location_gps_lat", dataType: configure.dataType.NUMBER },
|
|
1818
|
+
{ name: "location_gps_lng", dataType: configure.dataType.NUMBER },
|
|
1819
|
+
{ name: "location_address", dataType: configure.dataType.TEXT },
|
|
1820
|
+
{ name: "location_city", dataType: configure.dataType.TEXT },
|
|
1821
|
+
{ name: "location_country", dataType: configure.dataType.TEXT },
|
|
1822
|
+
{ name: "location_source", dataType: configure.dataType.TEXT },
|
|
1823
|
+
// Locale
|
|
1824
|
+
{ name: "locale_language", dataType: configure.dataType.TEXT },
|
|
1825
|
+
{ name: "locale_timezone", dataType: configure.dataType.TEXT },
|
|
1826
|
+
// Context
|
|
1827
|
+
{ name: "context_app", dataType: configure.dataType.TEXT },
|
|
1828
|
+
{ name: "context_url", dataType: configure.dataType.TEXT },
|
|
1829
|
+
{ name: "context_conversation_id", dataType: configure.dataType.TEXT },
|
|
1830
|
+
{ name: "context_summary", dataType: configure.dataType.TEXT },
|
|
1831
|
+
{ name: "context_timestamp", dataType: configure.dataType.DATE },
|
|
1832
|
+
// Relationships (v2 names)
|
|
1833
|
+
{ name: "relationship_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1834
|
+
{ name: "relationship_type", dataType: configure.dataType.TEXT },
|
|
1835
|
+
{ name: "related_memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1836
|
+
{ name: "observation", dataType: configure.dataType.TEXT },
|
|
1837
|
+
{ name: "source", dataType: configure.dataType.TEXT },
|
|
1838
|
+
// Relationships (v1 compat)
|
|
1839
|
+
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
1840
|
+
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1841
|
+
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
1842
|
+
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
1843
|
+
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
1844
|
+
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
1845
|
+
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
1846
|
+
// Access tracking
|
|
1847
|
+
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
1848
|
+
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
1849
|
+
// References & templates
|
|
1850
|
+
{ name: "references", dataType: configure.dataType.TEXT_ARRAY },
|
|
1851
|
+
{ name: "template_id", dataType: configure.dataType.TEXT },
|
|
1852
|
+
// Comments (Phase 1)
|
|
1853
|
+
{ name: "parent_id", dataType: configure.dataType.TEXT },
|
|
1854
|
+
{ name: "thread_root_id", dataType: configure.dataType.TEXT },
|
|
1855
|
+
{ name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
|
|
1856
|
+
// Agent follow-up tracking
|
|
1857
|
+
{ name: "follow_up_at", dataType: configure.dataType.DATE },
|
|
1858
|
+
// Soft delete
|
|
1859
|
+
{ name: "deleted_at", dataType: configure.dataType.DATE },
|
|
1860
|
+
{ name: "deleted_by", dataType: configure.dataType.TEXT },
|
|
1861
|
+
{ name: "deletion_reason", dataType: configure.dataType.TEXT }
|
|
1862
|
+
];
|
|
1863
|
+
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
1864
|
+
// Publication metadata
|
|
1865
|
+
{ name: "published_at", dataType: configure.dataType.DATE },
|
|
1866
|
+
{ name: "revised_at", dataType: configure.dataType.DATE },
|
|
1867
|
+
// Attribution
|
|
1868
|
+
{ name: "author_id", dataType: configure.dataType.TEXT },
|
|
1869
|
+
{ name: "ghost_id", dataType: configure.dataType.TEXT },
|
|
1870
|
+
{ name: "attribution", dataType: configure.dataType.TEXT },
|
|
1871
|
+
// Discovery
|
|
1872
|
+
{ name: "discovery_count", dataType: configure.dataType.INT },
|
|
1873
|
+
// Revision tracking
|
|
1874
|
+
{ name: "revision_count", dataType: configure.dataType.INT },
|
|
1875
|
+
{ name: "original_memory_id", dataType: configure.dataType.TEXT },
|
|
1876
|
+
// Moderation (nullable — null defaults to approved)
|
|
1877
|
+
{ name: "moderation_status", dataType: configure.dataType.TEXT },
|
|
1878
|
+
{ name: "moderated_by", dataType: configure.dataType.TEXT },
|
|
1879
|
+
{ name: "moderated_at", dataType: configure.dataType.DATE },
|
|
1880
|
+
// Memory-level ACL (nullable — null defaults to owner_only semantics)
|
|
1881
|
+
{ name: "write_mode", dataType: configure.dataType.TEXT },
|
|
1882
|
+
{ name: "owner_id", dataType: configure.dataType.TEXT },
|
|
1883
|
+
{ name: "overwrite_allowed_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1884
|
+
{ name: "last_revised_by", dataType: configure.dataType.TEXT },
|
|
1885
|
+
// Legacy compatibility (deprecated but kept for migration)
|
|
1886
|
+
{ name: "spaces", dataType: configure.dataType.TEXT_ARRAY },
|
|
1887
|
+
{ name: "space_id", dataType: configure.dataType.TEXT },
|
|
1888
|
+
{ name: "space_memory_id", dataType: configure.dataType.TEXT }
|
|
1889
|
+
];
|
|
1890
|
+
function createSpaceCollectionSchema() {
|
|
1891
|
+
const collectionName = "Memory_spaces_public";
|
|
1892
|
+
return {
|
|
1893
|
+
name: collectionName,
|
|
1894
|
+
description: "Shared memory collection for all public spaces",
|
|
1895
|
+
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
1896
|
+
model: "text-embedding-3-small",
|
|
1897
|
+
dimensions: 1536,
|
|
1898
|
+
vectorizeCollectionName: false
|
|
1899
|
+
}),
|
|
1900
|
+
properties: [
|
|
1901
|
+
...COMMON_MEMORY_PROPERTIES,
|
|
1902
|
+
...PUBLISHED_MEMORY_PROPERTIES
|
|
1903
|
+
],
|
|
1904
|
+
invertedIndex: configure.invertedIndex({
|
|
1905
|
+
indexNullState: true,
|
|
1906
|
+
indexPropertyLength: true,
|
|
1907
|
+
indexTimestamps: true
|
|
1908
|
+
})
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
function createGroupCollectionSchema(groupId) {
|
|
1912
|
+
const collectionName = `Memory_groups_${groupId}`;
|
|
1913
|
+
return {
|
|
1914
|
+
name: collectionName,
|
|
1915
|
+
description: `Group memory collection for group: ${groupId}`,
|
|
1916
|
+
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
1917
|
+
model: "text-embedding-3-small",
|
|
1918
|
+
dimensions: 1536,
|
|
1919
|
+
vectorizeCollectionName: false
|
|
1920
|
+
}),
|
|
1921
|
+
properties: [
|
|
1922
|
+
...COMMON_MEMORY_PROPERTIES,
|
|
1923
|
+
...PUBLISHED_MEMORY_PROPERTIES
|
|
1924
|
+
],
|
|
1925
|
+
invertedIndex: configure.invertedIndex({
|
|
1926
|
+
indexNullState: true,
|
|
1927
|
+
indexPropertyLength: true,
|
|
1928
|
+
indexTimestamps: true
|
|
1929
|
+
})
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
async function reconcileCollectionProperties(client2, collectionName, expectedProperties) {
|
|
1933
|
+
const collection = client2.collections.get(collectionName);
|
|
1934
|
+
const config2 = await collection.config.get();
|
|
1935
|
+
const existingNames = new Set(config2.properties.map((p) => p.name));
|
|
1936
|
+
let added = 0;
|
|
1937
|
+
for (const prop of expectedProperties) {
|
|
1938
|
+
if (!existingNames.has(prop.name)) {
|
|
1939
|
+
await collection.config.addProperty(prop);
|
|
1940
|
+
added++;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
return added;
|
|
1944
|
+
}
|
|
1945
|
+
async function ensureGroupCollection(client2, groupId) {
|
|
1946
|
+
const collectionName = `Memory_groups_${groupId}`;
|
|
1947
|
+
if (isCollectionCached(collectionName))
|
|
1948
|
+
return false;
|
|
1949
|
+
const exists = await client2.collections.exists(collectionName);
|
|
1950
|
+
if (exists) {
|
|
1951
|
+
await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
|
|
1952
|
+
cacheCollection(collectionName);
|
|
1953
|
+
return false;
|
|
1954
|
+
}
|
|
1955
|
+
const schema = createGroupCollectionSchema(groupId);
|
|
1956
|
+
await client2.collections.create(schema);
|
|
1957
|
+
await registerCollection({
|
|
1958
|
+
collection_name: collectionName,
|
|
1959
|
+
collection_type: "groups",
|
|
1960
|
+
owner_id: groupId,
|
|
1961
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1962
|
+
});
|
|
1963
|
+
cacheCollection(collectionName);
|
|
1964
|
+
return true;
|
|
1965
|
+
}
|
|
1966
|
+
function getCollectionType(collectionName) {
|
|
1967
|
+
if (collectionName.startsWith("Memory_users_"))
|
|
1968
|
+
return "users";
|
|
1969
|
+
if (collectionName === "Memory_spaces_public")
|
|
1970
|
+
return "spaces";
|
|
1971
|
+
if (collectionName.startsWith("Memory_groups_"))
|
|
1972
|
+
return "groups";
|
|
1973
|
+
throw new Error(`Unknown collection type for: ${collectionName}`);
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
// node_modules/@prmichaelsen/remember-core/dist/utils/dedupe.js
|
|
1977
|
+
function tagWithSource(objects, collectionName) {
|
|
1978
|
+
return objects.map((obj) => ({ ...obj, _collectionName: collectionName }));
|
|
1979
|
+
}
|
|
1980
|
+
function getTier(collectionName) {
|
|
1981
|
+
try {
|
|
1982
|
+
const type = getCollectionType(collectionName);
|
|
1983
|
+
switch (type) {
|
|
1984
|
+
case "spaces":
|
|
1985
|
+
return 1;
|
|
1986
|
+
case "groups":
|
|
1987
|
+
return 2;
|
|
1988
|
+
case "users":
|
|
1989
|
+
return 3;
|
|
1990
|
+
}
|
|
1991
|
+
} catch {
|
|
1992
|
+
return 4;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
function extractGroupId(collectionName) {
|
|
1996
|
+
if (collectionName.startsWith("Memory_groups_")) {
|
|
1997
|
+
return collectionName.replace("Memory_groups_", "");
|
|
1998
|
+
}
|
|
1999
|
+
return null;
|
|
2000
|
+
}
|
|
2001
|
+
function shouldPrefer(aCollection, bCollection, viewingGroupId) {
|
|
2002
|
+
const aTier = getTier(aCollection);
|
|
2003
|
+
const bTier = getTier(bCollection);
|
|
2004
|
+
if (aTier !== bTier)
|
|
2005
|
+
return aTier < bTier;
|
|
2006
|
+
if (viewingGroupId) {
|
|
2007
|
+
const aGroup = extractGroupId(aCollection);
|
|
2008
|
+
const bGroup = extractGroupId(bCollection);
|
|
2009
|
+
if (aGroup === viewingGroupId && bGroup !== viewingGroupId)
|
|
2010
|
+
return true;
|
|
2011
|
+
if (bGroup === viewingGroupId && aGroup !== viewingGroupId)
|
|
2012
|
+
return false;
|
|
2013
|
+
}
|
|
2014
|
+
return aCollection <= bCollection;
|
|
2015
|
+
}
|
|
2016
|
+
function dedupeBySourceId(objects, options = {}) {
|
|
2017
|
+
if (options.enabled === false)
|
|
2018
|
+
return objects;
|
|
2019
|
+
const sourceMap = /* @__PURE__ */ new Map();
|
|
2020
|
+
const results = [];
|
|
2021
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
2022
|
+
for (let i = 0; i < objects.length; i++) {
|
|
2023
|
+
const obj = objects[i];
|
|
2024
|
+
const sourceId = obj.properties.original_memory_id;
|
|
2025
|
+
if (!sourceId) {
|
|
2026
|
+
results.push({ obj, index: i });
|
|
2027
|
+
continue;
|
|
2028
|
+
}
|
|
2029
|
+
const existing = sourceMap.get(sourceId);
|
|
2030
|
+
if (!existing) {
|
|
2031
|
+
const tagged = { ...obj, _also_in: [] };
|
|
2032
|
+
sourceMap.set(sourceId, { winner: tagged, index: i });
|
|
2033
|
+
results.push({ obj: tagged, index: i });
|
|
2034
|
+
continue;
|
|
2035
|
+
}
|
|
2036
|
+
if (shouldPrefer(obj._collectionName, existing.winner._collectionName, options.viewingGroupId)) {
|
|
2037
|
+
existing.winner._also_in.push({
|
|
2038
|
+
source: obj._collectionName,
|
|
2039
|
+
id: obj.uuid
|
|
2040
|
+
});
|
|
2041
|
+
const loser = existing.winner;
|
|
2042
|
+
const newWinner = {
|
|
2043
|
+
...obj,
|
|
2044
|
+
_also_in: [
|
|
2045
|
+
...existing.winner._also_in.filter((a) => a.id !== obj.uuid),
|
|
2046
|
+
{ source: loser._collectionName, id: loser.uuid }
|
|
2047
|
+
]
|
|
2048
|
+
};
|
|
2049
|
+
deduped.add(loser.uuid);
|
|
2050
|
+
deduped.delete(obj.uuid);
|
|
2051
|
+
sourceMap.set(sourceId, { winner: newWinner, index: i });
|
|
2052
|
+
const oldSlot = results.find((r) => r.obj.uuid === loser.uuid);
|
|
2053
|
+
if (oldSlot) {
|
|
2054
|
+
oldSlot.obj = newWinner;
|
|
2055
|
+
oldSlot.index = i;
|
|
2056
|
+
}
|
|
2057
|
+
} else {
|
|
2058
|
+
existing.winner._also_in.push({
|
|
2059
|
+
source: obj._collectionName,
|
|
2060
|
+
id: obj.uuid
|
|
2061
|
+
});
|
|
2062
|
+
deduped.add(obj.uuid);
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
return results.filter((r) => !deduped.has(r.obj.uuid)).map((r) => r.obj);
|
|
2066
|
+
}
|
|
2067
|
+
|
|
1761
2068
|
// node_modules/@prmichaelsen/remember-core/dist/services/preferences.service.js
|
|
1762
2069
|
var PreferencesDatabaseService = class {
|
|
1763
2070
|
logger;
|
|
@@ -2880,212 +3187,6 @@ var RelationshipService = class {
|
|
|
2880
3187
|
// node_modules/@prmichaelsen/remember-core/dist/services/space.service.js
|
|
2881
3188
|
import { Filters as Filters4 } from "weaviate-client";
|
|
2882
3189
|
|
|
2883
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
2884
|
-
import { configure } from "weaviate-client";
|
|
2885
|
-
|
|
2886
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/collection-registry.js
|
|
2887
|
-
async function registerCollection(entry) {
|
|
2888
|
-
const path = getCollectionRegistryPath();
|
|
2889
|
-
await setDocument2(path, entry.collection_name, entry);
|
|
2890
|
-
}
|
|
2891
|
-
|
|
2892
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
2893
|
-
var collectionCache = /* @__PURE__ */ new Map();
|
|
2894
|
-
var COLLECTION_CACHE_TTL_MS = 6e4;
|
|
2895
|
-
function isCollectionCached(collectionName) {
|
|
2896
|
-
const expiresAt = collectionCache.get(collectionName);
|
|
2897
|
-
if (expiresAt !== void 0 && Date.now() < expiresAt)
|
|
2898
|
-
return true;
|
|
2899
|
-
collectionCache.delete(collectionName);
|
|
2900
|
-
return false;
|
|
2901
|
-
}
|
|
2902
|
-
function cacheCollection(collectionName) {
|
|
2903
|
-
collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
|
|
2904
|
-
}
|
|
2905
|
-
var COMMON_MEMORY_PROPERTIES = [
|
|
2906
|
-
// Core content
|
|
2907
|
-
{ name: "content", dataType: configure.dataType.TEXT },
|
|
2908
|
-
{ name: "content_type", dataType: configure.dataType.TEXT },
|
|
2909
|
-
{ name: "title", dataType: configure.dataType.TEXT },
|
|
2910
|
-
{ name: "summary", dataType: configure.dataType.TEXT },
|
|
2911
|
-
{ name: "type", dataType: configure.dataType.TEXT },
|
|
2912
|
-
// v1 compat (v2: content_type)
|
|
2913
|
-
// Tracking arrays (v2 feature)
|
|
2914
|
-
{ name: "space_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2915
|
-
{ name: "group_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2916
|
-
// Metadata
|
|
2917
|
-
{ name: "created_at", dataType: configure.dataType.DATE },
|
|
2918
|
-
{ name: "updated_at", dataType: configure.dataType.DATE },
|
|
2919
|
-
{ name: "version", dataType: configure.dataType.INT },
|
|
2920
|
-
// User context
|
|
2921
|
-
{ name: "user_id", dataType: configure.dataType.TEXT },
|
|
2922
|
-
// Document type (memory, relationship, comment)
|
|
2923
|
-
{ name: "doc_type", dataType: configure.dataType.TEXT },
|
|
2924
|
-
// Memory-specific fields
|
|
2925
|
-
{ name: "tags", dataType: configure.dataType.TEXT_ARRAY },
|
|
2926
|
-
{ name: "weight", dataType: configure.dataType.NUMBER },
|
|
2927
|
-
{ name: "trust_score", dataType: configure.dataType.NUMBER },
|
|
2928
|
-
{ name: "trust", dataType: configure.dataType.NUMBER },
|
|
2929
|
-
// v1 compat (v2: trust_score)
|
|
2930
|
-
{ name: "base_weight", dataType: configure.dataType.NUMBER },
|
|
2931
|
-
{ name: "computed_weight", dataType: configure.dataType.NUMBER },
|
|
2932
|
-
{ name: "confidence", dataType: configure.dataType.NUMBER },
|
|
2933
|
-
{ name: "strength", dataType: configure.dataType.NUMBER },
|
|
2934
|
-
// Location data (v2 names)
|
|
2935
|
-
{ name: "location_name", dataType: configure.dataType.TEXT },
|
|
2936
|
-
{ name: "location_lat", dataType: configure.dataType.NUMBER },
|
|
2937
|
-
{ name: "location_lon", dataType: configure.dataType.NUMBER },
|
|
2938
|
-
// Location data (v1 compat)
|
|
2939
|
-
{ name: "location_gps_lat", dataType: configure.dataType.NUMBER },
|
|
2940
|
-
{ name: "location_gps_lng", dataType: configure.dataType.NUMBER },
|
|
2941
|
-
{ name: "location_address", dataType: configure.dataType.TEXT },
|
|
2942
|
-
{ name: "location_city", dataType: configure.dataType.TEXT },
|
|
2943
|
-
{ name: "location_country", dataType: configure.dataType.TEXT },
|
|
2944
|
-
{ name: "location_source", dataType: configure.dataType.TEXT },
|
|
2945
|
-
// Locale
|
|
2946
|
-
{ name: "locale_language", dataType: configure.dataType.TEXT },
|
|
2947
|
-
{ name: "locale_timezone", dataType: configure.dataType.TEXT },
|
|
2948
|
-
// Context
|
|
2949
|
-
{ name: "context_app", dataType: configure.dataType.TEXT },
|
|
2950
|
-
{ name: "context_url", dataType: configure.dataType.TEXT },
|
|
2951
|
-
{ name: "context_conversation_id", dataType: configure.dataType.TEXT },
|
|
2952
|
-
{ name: "context_summary", dataType: configure.dataType.TEXT },
|
|
2953
|
-
{ name: "context_timestamp", dataType: configure.dataType.DATE },
|
|
2954
|
-
// Relationships (v2 names)
|
|
2955
|
-
{ name: "relationship_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2956
|
-
{ name: "relationship_type", dataType: configure.dataType.TEXT },
|
|
2957
|
-
{ name: "related_memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2958
|
-
{ name: "observation", dataType: configure.dataType.TEXT },
|
|
2959
|
-
{ name: "source", dataType: configure.dataType.TEXT },
|
|
2960
|
-
// Relationships (v1 compat)
|
|
2961
|
-
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
2962
|
-
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2963
|
-
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
2964
|
-
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
2965
|
-
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
2966
|
-
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
2967
|
-
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
2968
|
-
// Access tracking
|
|
2969
|
-
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
2970
|
-
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
2971
|
-
// References & templates
|
|
2972
|
-
{ name: "references", dataType: configure.dataType.TEXT_ARRAY },
|
|
2973
|
-
{ name: "template_id", dataType: configure.dataType.TEXT },
|
|
2974
|
-
// Comments (Phase 1)
|
|
2975
|
-
{ name: "parent_id", dataType: configure.dataType.TEXT },
|
|
2976
|
-
{ name: "thread_root_id", dataType: configure.dataType.TEXT },
|
|
2977
|
-
{ name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
|
|
2978
|
-
// Agent follow-up tracking
|
|
2979
|
-
{ name: "follow_up_at", dataType: configure.dataType.DATE },
|
|
2980
|
-
// Soft delete
|
|
2981
|
-
{ name: "deleted_at", dataType: configure.dataType.DATE },
|
|
2982
|
-
{ name: "deleted_by", dataType: configure.dataType.TEXT },
|
|
2983
|
-
{ name: "deletion_reason", dataType: configure.dataType.TEXT }
|
|
2984
|
-
];
|
|
2985
|
-
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
2986
|
-
// Publication metadata
|
|
2987
|
-
{ name: "published_at", dataType: configure.dataType.DATE },
|
|
2988
|
-
{ name: "revised_at", dataType: configure.dataType.DATE },
|
|
2989
|
-
// Attribution
|
|
2990
|
-
{ name: "author_id", dataType: configure.dataType.TEXT },
|
|
2991
|
-
{ name: "ghost_id", dataType: configure.dataType.TEXT },
|
|
2992
|
-
{ name: "attribution", dataType: configure.dataType.TEXT },
|
|
2993
|
-
// Discovery
|
|
2994
|
-
{ name: "discovery_count", dataType: configure.dataType.INT },
|
|
2995
|
-
// Revision tracking
|
|
2996
|
-
{ name: "revision_count", dataType: configure.dataType.INT },
|
|
2997
|
-
{ name: "original_memory_id", dataType: configure.dataType.TEXT },
|
|
2998
|
-
// Moderation (nullable — null defaults to approved)
|
|
2999
|
-
{ name: "moderation_status", dataType: configure.dataType.TEXT },
|
|
3000
|
-
{ name: "moderated_by", dataType: configure.dataType.TEXT },
|
|
3001
|
-
{ name: "moderated_at", dataType: configure.dataType.DATE },
|
|
3002
|
-
// Memory-level ACL (nullable — null defaults to owner_only semantics)
|
|
3003
|
-
{ name: "write_mode", dataType: configure.dataType.TEXT },
|
|
3004
|
-
{ name: "owner_id", dataType: configure.dataType.TEXT },
|
|
3005
|
-
{ name: "overwrite_allowed_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
3006
|
-
{ name: "last_revised_by", dataType: configure.dataType.TEXT },
|
|
3007
|
-
// Legacy compatibility (deprecated but kept for migration)
|
|
3008
|
-
{ name: "spaces", dataType: configure.dataType.TEXT_ARRAY },
|
|
3009
|
-
{ name: "space_id", dataType: configure.dataType.TEXT },
|
|
3010
|
-
{ name: "space_memory_id", dataType: configure.dataType.TEXT }
|
|
3011
|
-
];
|
|
3012
|
-
function createSpaceCollectionSchema() {
|
|
3013
|
-
const collectionName = "Memory_spaces_public";
|
|
3014
|
-
return {
|
|
3015
|
-
name: collectionName,
|
|
3016
|
-
description: "Shared memory collection for all public spaces",
|
|
3017
|
-
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
3018
|
-
model: "text-embedding-3-small",
|
|
3019
|
-
dimensions: 1536,
|
|
3020
|
-
vectorizeCollectionName: false
|
|
3021
|
-
}),
|
|
3022
|
-
properties: [
|
|
3023
|
-
...COMMON_MEMORY_PROPERTIES,
|
|
3024
|
-
...PUBLISHED_MEMORY_PROPERTIES
|
|
3025
|
-
],
|
|
3026
|
-
invertedIndex: configure.invertedIndex({
|
|
3027
|
-
indexNullState: true,
|
|
3028
|
-
indexPropertyLength: true,
|
|
3029
|
-
indexTimestamps: true
|
|
3030
|
-
})
|
|
3031
|
-
};
|
|
3032
|
-
}
|
|
3033
|
-
function createGroupCollectionSchema(groupId) {
|
|
3034
|
-
const collectionName = `Memory_groups_${groupId}`;
|
|
3035
|
-
return {
|
|
3036
|
-
name: collectionName,
|
|
3037
|
-
description: `Group memory collection for group: ${groupId}`,
|
|
3038
|
-
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
3039
|
-
model: "text-embedding-3-small",
|
|
3040
|
-
dimensions: 1536,
|
|
3041
|
-
vectorizeCollectionName: false
|
|
3042
|
-
}),
|
|
3043
|
-
properties: [
|
|
3044
|
-
...COMMON_MEMORY_PROPERTIES,
|
|
3045
|
-
...PUBLISHED_MEMORY_PROPERTIES
|
|
3046
|
-
],
|
|
3047
|
-
invertedIndex: configure.invertedIndex({
|
|
3048
|
-
indexNullState: true,
|
|
3049
|
-
indexPropertyLength: true,
|
|
3050
|
-
indexTimestamps: true
|
|
3051
|
-
})
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
async function reconcileCollectionProperties(client2, collectionName, expectedProperties) {
|
|
3055
|
-
const collection = client2.collections.get(collectionName);
|
|
3056
|
-
const config2 = await collection.config.get();
|
|
3057
|
-
const existingNames = new Set(config2.properties.map((p) => p.name));
|
|
3058
|
-
let added = 0;
|
|
3059
|
-
for (const prop of expectedProperties) {
|
|
3060
|
-
if (!existingNames.has(prop.name)) {
|
|
3061
|
-
await collection.config.addProperty(prop);
|
|
3062
|
-
added++;
|
|
3063
|
-
}
|
|
3064
|
-
}
|
|
3065
|
-
return added;
|
|
3066
|
-
}
|
|
3067
|
-
async function ensureGroupCollection(client2, groupId) {
|
|
3068
|
-
const collectionName = `Memory_groups_${groupId}`;
|
|
3069
|
-
if (isCollectionCached(collectionName))
|
|
3070
|
-
return false;
|
|
3071
|
-
const exists = await client2.collections.exists(collectionName);
|
|
3072
|
-
if (exists) {
|
|
3073
|
-
await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
|
|
3074
|
-
cacheCollection(collectionName);
|
|
3075
|
-
return false;
|
|
3076
|
-
}
|
|
3077
|
-
const schema = createGroupCollectionSchema(groupId);
|
|
3078
|
-
await client2.collections.create(schema);
|
|
3079
|
-
await registerCollection({
|
|
3080
|
-
collection_name: collectionName,
|
|
3081
|
-
collection_type: "groups",
|
|
3082
|
-
owner_id: groupId,
|
|
3083
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3084
|
-
});
|
|
3085
|
-
cacheCollection(collectionName);
|
|
3086
|
-
return true;
|
|
3087
|
-
}
|
|
3088
|
-
|
|
3089
3190
|
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/space-schema.js
|
|
3090
3191
|
var PUBLIC_COLLECTION_NAME = "Memory_spaces_public";
|
|
3091
3192
|
function isValidSpaceId(spaceId) {
|
|
@@ -3403,7 +3504,7 @@ var SpaceService = class {
|
|
|
3403
3504
|
}
|
|
3404
3505
|
const combinedFilters = filterList.length > 0 ? Filters4.and(...filterList) : void 0;
|
|
3405
3506
|
const spaceObjects = await this.executeSearch(spacesCollection, input.query, searchType, combinedFilters, fetchLimit);
|
|
3406
|
-
allObjects.push(...spaceObjects);
|
|
3507
|
+
allObjects.push(...tagWithSource(spaceObjects, spacesCollectionName));
|
|
3407
3508
|
}
|
|
3408
3509
|
for (const groupId of groups) {
|
|
3409
3510
|
const groupCollectionName = getCollectionName(CollectionType.GROUPS, groupId);
|
|
@@ -3414,24 +3515,26 @@ var SpaceService = class {
|
|
|
3414
3515
|
const filterList = this.buildBaseFilters(groupCollection, input);
|
|
3415
3516
|
const combinedFilters = filterList.length > 0 ? Filters4.and(...filterList) : void 0;
|
|
3416
3517
|
const groupObjects = await this.executeSearch(groupCollection, input.query, searchType, combinedFilters, fetchLimit);
|
|
3417
|
-
allObjects.push(...groupObjects);
|
|
3518
|
+
allObjects.push(...tagWithSource(groupObjects, groupCollectionName));
|
|
3418
3519
|
}
|
|
3419
3520
|
const seen = /* @__PURE__ */ new Set();
|
|
3420
|
-
const
|
|
3521
|
+
const uuidDeduped = allObjects.filter((obj) => {
|
|
3421
3522
|
if (seen.has(obj.uuid))
|
|
3422
3523
|
return false;
|
|
3423
3524
|
seen.add(obj.uuid);
|
|
3424
3525
|
return true;
|
|
3425
3526
|
});
|
|
3426
|
-
|
|
3527
|
+
const contentDeduped = dedupeBySourceId(uuidDeduped, input.dedupe);
|
|
3528
|
+
contentDeduped.sort((a, b) => {
|
|
3427
3529
|
const scoreA = a.metadata?.score ?? 0;
|
|
3428
3530
|
const scoreB = b.metadata?.score ?? 0;
|
|
3429
3531
|
return scoreB - scoreA;
|
|
3430
3532
|
});
|
|
3431
|
-
const paginated =
|
|
3533
|
+
const paginated = contentDeduped.slice(offset, offset + limit);
|
|
3432
3534
|
const memories = paginated.map((obj) => ({
|
|
3433
3535
|
id: obj.uuid,
|
|
3434
|
-
...obj.properties
|
|
3536
|
+
...obj.properties,
|
|
3537
|
+
...obj._also_in?.length ? { also_in: obj._also_in } : {}
|
|
3435
3538
|
}));
|
|
3436
3539
|
const isAllPublic = spaces.length === 0 && groups.length === 0;
|
|
3437
3540
|
return {
|
|
@@ -3550,7 +3653,8 @@ var SpaceService = class {
|
|
|
3550
3653
|
discovery_count: 0,
|
|
3551
3654
|
attribution: "user",
|
|
3552
3655
|
moderation_status: spaceModerationStatus,
|
|
3553
|
-
tags: mergedTags
|
|
3656
|
+
tags: mergedTags,
|
|
3657
|
+
original_memory_id: request.payload.memory_id
|
|
3554
3658
|
};
|
|
3555
3659
|
delete publishedMemory._additional;
|
|
3556
3660
|
if (existingSpaceMemory) {
|
|
@@ -3591,7 +3695,8 @@ var SpaceService = class {
|
|
|
3591
3695
|
discovery_count: 0,
|
|
3592
3696
|
attribution: "user",
|
|
3593
3697
|
moderation_status: groupModerationStatus,
|
|
3594
|
-
tags: mergedTags
|
|
3698
|
+
tags: mergedTags,
|
|
3699
|
+
original_memory_id: request.payload.memory_id
|
|
3595
3700
|
};
|
|
3596
3701
|
delete groupMemory._additional;
|
|
3597
3702
|
if (existingGroupMemory) {
|
package/dist/server.js
CHANGED
|
@@ -1730,6 +1730,9 @@ function canModerateAny(authContext) {
|
|
|
1730
1730
|
return authContext.credentials.group_memberships.some((m) => m.permissions.can_moderate);
|
|
1731
1731
|
}
|
|
1732
1732
|
|
|
1733
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
1734
|
+
import { configure } from "weaviate-client";
|
|
1735
|
+
|
|
1733
1736
|
// node_modules/@prmichaelsen/remember-core/dist/database/firestore/init.js
|
|
1734
1737
|
import { initializeApp as initializeApp2 } from "@prmichaelsen/firebase-admin-sdk-v8";
|
|
1735
1738
|
import { getDocument as getDocument2, setDocument as setDocument2, addDocument as addDocument2, updateDocument as updateDocument2, deleteDocument as deleteDocument2, queryDocuments as queryDocuments2, batchWrite as batchWrite2, FieldValue as FieldValue2, verifyIdToken as verifyIdToken2 } from "@prmichaelsen/firebase-admin-sdk-v8";
|
|
@@ -1762,6 +1765,310 @@ function getMemoryIndexPath() {
|
|
|
1762
1765
|
return `${BASE}.memory_index`;
|
|
1763
1766
|
}
|
|
1764
1767
|
|
|
1768
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/collection-registry.js
|
|
1769
|
+
async function registerCollection(entry) {
|
|
1770
|
+
const path = getCollectionRegistryPath();
|
|
1771
|
+
await setDocument2(path, entry.collection_name, entry);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
1775
|
+
var collectionCache = /* @__PURE__ */ new Map();
|
|
1776
|
+
var COLLECTION_CACHE_TTL_MS = 6e4;
|
|
1777
|
+
function isCollectionCached(collectionName) {
|
|
1778
|
+
const expiresAt = collectionCache.get(collectionName);
|
|
1779
|
+
if (expiresAt !== void 0 && Date.now() < expiresAt)
|
|
1780
|
+
return true;
|
|
1781
|
+
collectionCache.delete(collectionName);
|
|
1782
|
+
return false;
|
|
1783
|
+
}
|
|
1784
|
+
function cacheCollection(collectionName) {
|
|
1785
|
+
collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
|
|
1786
|
+
}
|
|
1787
|
+
var COMMON_MEMORY_PROPERTIES = [
|
|
1788
|
+
// Core content
|
|
1789
|
+
{ name: "content", dataType: configure.dataType.TEXT },
|
|
1790
|
+
{ name: "content_type", dataType: configure.dataType.TEXT },
|
|
1791
|
+
{ name: "title", dataType: configure.dataType.TEXT },
|
|
1792
|
+
{ name: "summary", dataType: configure.dataType.TEXT },
|
|
1793
|
+
{ name: "type", dataType: configure.dataType.TEXT },
|
|
1794
|
+
// v1 compat (v2: content_type)
|
|
1795
|
+
// Tracking arrays (v2 feature)
|
|
1796
|
+
{ name: "space_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1797
|
+
{ name: "group_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1798
|
+
// Metadata
|
|
1799
|
+
{ name: "created_at", dataType: configure.dataType.DATE },
|
|
1800
|
+
{ name: "updated_at", dataType: configure.dataType.DATE },
|
|
1801
|
+
{ name: "version", dataType: configure.dataType.INT },
|
|
1802
|
+
// User context
|
|
1803
|
+
{ name: "user_id", dataType: configure.dataType.TEXT },
|
|
1804
|
+
// Document type (memory, relationship, comment)
|
|
1805
|
+
{ name: "doc_type", dataType: configure.dataType.TEXT },
|
|
1806
|
+
// Memory-specific fields
|
|
1807
|
+
{ name: "tags", dataType: configure.dataType.TEXT_ARRAY },
|
|
1808
|
+
{ name: "weight", dataType: configure.dataType.NUMBER },
|
|
1809
|
+
{ name: "trust_score", dataType: configure.dataType.NUMBER },
|
|
1810
|
+
{ name: "trust", dataType: configure.dataType.NUMBER },
|
|
1811
|
+
// v1 compat (v2: trust_score)
|
|
1812
|
+
{ name: "base_weight", dataType: configure.dataType.NUMBER },
|
|
1813
|
+
{ name: "computed_weight", dataType: configure.dataType.NUMBER },
|
|
1814
|
+
{ name: "confidence", dataType: configure.dataType.NUMBER },
|
|
1815
|
+
{ name: "strength", dataType: configure.dataType.NUMBER },
|
|
1816
|
+
// Location data (v2 names)
|
|
1817
|
+
{ name: "location_name", dataType: configure.dataType.TEXT },
|
|
1818
|
+
{ name: "location_lat", dataType: configure.dataType.NUMBER },
|
|
1819
|
+
{ name: "location_lon", dataType: configure.dataType.NUMBER },
|
|
1820
|
+
// Location data (v1 compat)
|
|
1821
|
+
{ name: "location_gps_lat", dataType: configure.dataType.NUMBER },
|
|
1822
|
+
{ name: "location_gps_lng", dataType: configure.dataType.NUMBER },
|
|
1823
|
+
{ name: "location_address", dataType: configure.dataType.TEXT },
|
|
1824
|
+
{ name: "location_city", dataType: configure.dataType.TEXT },
|
|
1825
|
+
{ name: "location_country", dataType: configure.dataType.TEXT },
|
|
1826
|
+
{ name: "location_source", dataType: configure.dataType.TEXT },
|
|
1827
|
+
// Locale
|
|
1828
|
+
{ name: "locale_language", dataType: configure.dataType.TEXT },
|
|
1829
|
+
{ name: "locale_timezone", dataType: configure.dataType.TEXT },
|
|
1830
|
+
// Context
|
|
1831
|
+
{ name: "context_app", dataType: configure.dataType.TEXT },
|
|
1832
|
+
{ name: "context_url", dataType: configure.dataType.TEXT },
|
|
1833
|
+
{ name: "context_conversation_id", dataType: configure.dataType.TEXT },
|
|
1834
|
+
{ name: "context_summary", dataType: configure.dataType.TEXT },
|
|
1835
|
+
{ name: "context_timestamp", dataType: configure.dataType.DATE },
|
|
1836
|
+
// Relationships (v2 names)
|
|
1837
|
+
{ name: "relationship_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1838
|
+
{ name: "relationship_type", dataType: configure.dataType.TEXT },
|
|
1839
|
+
{ name: "related_memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1840
|
+
{ name: "observation", dataType: configure.dataType.TEXT },
|
|
1841
|
+
{ name: "source", dataType: configure.dataType.TEXT },
|
|
1842
|
+
// Relationships (v1 compat)
|
|
1843
|
+
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
1844
|
+
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1845
|
+
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
1846
|
+
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
1847
|
+
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
1848
|
+
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
1849
|
+
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
1850
|
+
// Access tracking
|
|
1851
|
+
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
1852
|
+
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
1853
|
+
// References & templates
|
|
1854
|
+
{ name: "references", dataType: configure.dataType.TEXT_ARRAY },
|
|
1855
|
+
{ name: "template_id", dataType: configure.dataType.TEXT },
|
|
1856
|
+
// Comments (Phase 1)
|
|
1857
|
+
{ name: "parent_id", dataType: configure.dataType.TEXT },
|
|
1858
|
+
{ name: "thread_root_id", dataType: configure.dataType.TEXT },
|
|
1859
|
+
{ name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
|
|
1860
|
+
// Agent follow-up tracking
|
|
1861
|
+
{ name: "follow_up_at", dataType: configure.dataType.DATE },
|
|
1862
|
+
// Soft delete
|
|
1863
|
+
{ name: "deleted_at", dataType: configure.dataType.DATE },
|
|
1864
|
+
{ name: "deleted_by", dataType: configure.dataType.TEXT },
|
|
1865
|
+
{ name: "deletion_reason", dataType: configure.dataType.TEXT }
|
|
1866
|
+
];
|
|
1867
|
+
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
1868
|
+
// Publication metadata
|
|
1869
|
+
{ name: "published_at", dataType: configure.dataType.DATE },
|
|
1870
|
+
{ name: "revised_at", dataType: configure.dataType.DATE },
|
|
1871
|
+
// Attribution
|
|
1872
|
+
{ name: "author_id", dataType: configure.dataType.TEXT },
|
|
1873
|
+
{ name: "ghost_id", dataType: configure.dataType.TEXT },
|
|
1874
|
+
{ name: "attribution", dataType: configure.dataType.TEXT },
|
|
1875
|
+
// Discovery
|
|
1876
|
+
{ name: "discovery_count", dataType: configure.dataType.INT },
|
|
1877
|
+
// Revision tracking
|
|
1878
|
+
{ name: "revision_count", dataType: configure.dataType.INT },
|
|
1879
|
+
{ name: "original_memory_id", dataType: configure.dataType.TEXT },
|
|
1880
|
+
// Moderation (nullable — null defaults to approved)
|
|
1881
|
+
{ name: "moderation_status", dataType: configure.dataType.TEXT },
|
|
1882
|
+
{ name: "moderated_by", dataType: configure.dataType.TEXT },
|
|
1883
|
+
{ name: "moderated_at", dataType: configure.dataType.DATE },
|
|
1884
|
+
// Memory-level ACL (nullable — null defaults to owner_only semantics)
|
|
1885
|
+
{ name: "write_mode", dataType: configure.dataType.TEXT },
|
|
1886
|
+
{ name: "owner_id", dataType: configure.dataType.TEXT },
|
|
1887
|
+
{ name: "overwrite_allowed_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
1888
|
+
{ name: "last_revised_by", dataType: configure.dataType.TEXT },
|
|
1889
|
+
// Legacy compatibility (deprecated but kept for migration)
|
|
1890
|
+
{ name: "spaces", dataType: configure.dataType.TEXT_ARRAY },
|
|
1891
|
+
{ name: "space_id", dataType: configure.dataType.TEXT },
|
|
1892
|
+
{ name: "space_memory_id", dataType: configure.dataType.TEXT }
|
|
1893
|
+
];
|
|
1894
|
+
function createSpaceCollectionSchema() {
|
|
1895
|
+
const collectionName = "Memory_spaces_public";
|
|
1896
|
+
return {
|
|
1897
|
+
name: collectionName,
|
|
1898
|
+
description: "Shared memory collection for all public spaces",
|
|
1899
|
+
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
1900
|
+
model: "text-embedding-3-small",
|
|
1901
|
+
dimensions: 1536,
|
|
1902
|
+
vectorizeCollectionName: false
|
|
1903
|
+
}),
|
|
1904
|
+
properties: [
|
|
1905
|
+
...COMMON_MEMORY_PROPERTIES,
|
|
1906
|
+
...PUBLISHED_MEMORY_PROPERTIES
|
|
1907
|
+
],
|
|
1908
|
+
invertedIndex: configure.invertedIndex({
|
|
1909
|
+
indexNullState: true,
|
|
1910
|
+
indexPropertyLength: true,
|
|
1911
|
+
indexTimestamps: true
|
|
1912
|
+
})
|
|
1913
|
+
};
|
|
1914
|
+
}
|
|
1915
|
+
function createGroupCollectionSchema(groupId) {
|
|
1916
|
+
const collectionName = `Memory_groups_${groupId}`;
|
|
1917
|
+
return {
|
|
1918
|
+
name: collectionName,
|
|
1919
|
+
description: `Group memory collection for group: ${groupId}`,
|
|
1920
|
+
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
1921
|
+
model: "text-embedding-3-small",
|
|
1922
|
+
dimensions: 1536,
|
|
1923
|
+
vectorizeCollectionName: false
|
|
1924
|
+
}),
|
|
1925
|
+
properties: [
|
|
1926
|
+
...COMMON_MEMORY_PROPERTIES,
|
|
1927
|
+
...PUBLISHED_MEMORY_PROPERTIES
|
|
1928
|
+
],
|
|
1929
|
+
invertedIndex: configure.invertedIndex({
|
|
1930
|
+
indexNullState: true,
|
|
1931
|
+
indexPropertyLength: true,
|
|
1932
|
+
indexTimestamps: true
|
|
1933
|
+
})
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
async function reconcileCollectionProperties(client2, collectionName, expectedProperties) {
|
|
1937
|
+
const collection = client2.collections.get(collectionName);
|
|
1938
|
+
const config3 = await collection.config.get();
|
|
1939
|
+
const existingNames = new Set(config3.properties.map((p) => p.name));
|
|
1940
|
+
let added = 0;
|
|
1941
|
+
for (const prop of expectedProperties) {
|
|
1942
|
+
if (!existingNames.has(prop.name)) {
|
|
1943
|
+
await collection.config.addProperty(prop);
|
|
1944
|
+
added++;
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return added;
|
|
1948
|
+
}
|
|
1949
|
+
async function ensureGroupCollection(client2, groupId) {
|
|
1950
|
+
const collectionName = `Memory_groups_${groupId}`;
|
|
1951
|
+
if (isCollectionCached(collectionName))
|
|
1952
|
+
return false;
|
|
1953
|
+
const exists = await client2.collections.exists(collectionName);
|
|
1954
|
+
if (exists) {
|
|
1955
|
+
await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
|
|
1956
|
+
cacheCollection(collectionName);
|
|
1957
|
+
return false;
|
|
1958
|
+
}
|
|
1959
|
+
const schema = createGroupCollectionSchema(groupId);
|
|
1960
|
+
await client2.collections.create(schema);
|
|
1961
|
+
await registerCollection({
|
|
1962
|
+
collection_name: collectionName,
|
|
1963
|
+
collection_type: "groups",
|
|
1964
|
+
owner_id: groupId,
|
|
1965
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1966
|
+
});
|
|
1967
|
+
cacheCollection(collectionName);
|
|
1968
|
+
return true;
|
|
1969
|
+
}
|
|
1970
|
+
function getCollectionType(collectionName) {
|
|
1971
|
+
if (collectionName.startsWith("Memory_users_"))
|
|
1972
|
+
return "users";
|
|
1973
|
+
if (collectionName === "Memory_spaces_public")
|
|
1974
|
+
return "spaces";
|
|
1975
|
+
if (collectionName.startsWith("Memory_groups_"))
|
|
1976
|
+
return "groups";
|
|
1977
|
+
throw new Error(`Unknown collection type for: ${collectionName}`);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
// node_modules/@prmichaelsen/remember-core/dist/utils/dedupe.js
|
|
1981
|
+
function tagWithSource(objects, collectionName) {
|
|
1982
|
+
return objects.map((obj) => ({ ...obj, _collectionName: collectionName }));
|
|
1983
|
+
}
|
|
1984
|
+
function getTier(collectionName) {
|
|
1985
|
+
try {
|
|
1986
|
+
const type = getCollectionType(collectionName);
|
|
1987
|
+
switch (type) {
|
|
1988
|
+
case "spaces":
|
|
1989
|
+
return 1;
|
|
1990
|
+
case "groups":
|
|
1991
|
+
return 2;
|
|
1992
|
+
case "users":
|
|
1993
|
+
return 3;
|
|
1994
|
+
}
|
|
1995
|
+
} catch {
|
|
1996
|
+
return 4;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
function extractGroupId(collectionName) {
|
|
2000
|
+
if (collectionName.startsWith("Memory_groups_")) {
|
|
2001
|
+
return collectionName.replace("Memory_groups_", "");
|
|
2002
|
+
}
|
|
2003
|
+
return null;
|
|
2004
|
+
}
|
|
2005
|
+
function shouldPrefer(aCollection, bCollection, viewingGroupId) {
|
|
2006
|
+
const aTier = getTier(aCollection);
|
|
2007
|
+
const bTier = getTier(bCollection);
|
|
2008
|
+
if (aTier !== bTier)
|
|
2009
|
+
return aTier < bTier;
|
|
2010
|
+
if (viewingGroupId) {
|
|
2011
|
+
const aGroup = extractGroupId(aCollection);
|
|
2012
|
+
const bGroup = extractGroupId(bCollection);
|
|
2013
|
+
if (aGroup === viewingGroupId && bGroup !== viewingGroupId)
|
|
2014
|
+
return true;
|
|
2015
|
+
if (bGroup === viewingGroupId && aGroup !== viewingGroupId)
|
|
2016
|
+
return false;
|
|
2017
|
+
}
|
|
2018
|
+
return aCollection <= bCollection;
|
|
2019
|
+
}
|
|
2020
|
+
function dedupeBySourceId(objects, options = {}) {
|
|
2021
|
+
if (options.enabled === false)
|
|
2022
|
+
return objects;
|
|
2023
|
+
const sourceMap = /* @__PURE__ */ new Map();
|
|
2024
|
+
const results = [];
|
|
2025
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
2026
|
+
for (let i = 0; i < objects.length; i++) {
|
|
2027
|
+
const obj = objects[i];
|
|
2028
|
+
const sourceId = obj.properties.original_memory_id;
|
|
2029
|
+
if (!sourceId) {
|
|
2030
|
+
results.push({ obj, index: i });
|
|
2031
|
+
continue;
|
|
2032
|
+
}
|
|
2033
|
+
const existing = sourceMap.get(sourceId);
|
|
2034
|
+
if (!existing) {
|
|
2035
|
+
const tagged = { ...obj, _also_in: [] };
|
|
2036
|
+
sourceMap.set(sourceId, { winner: tagged, index: i });
|
|
2037
|
+
results.push({ obj: tagged, index: i });
|
|
2038
|
+
continue;
|
|
2039
|
+
}
|
|
2040
|
+
if (shouldPrefer(obj._collectionName, existing.winner._collectionName, options.viewingGroupId)) {
|
|
2041
|
+
existing.winner._also_in.push({
|
|
2042
|
+
source: obj._collectionName,
|
|
2043
|
+
id: obj.uuid
|
|
2044
|
+
});
|
|
2045
|
+
const loser = existing.winner;
|
|
2046
|
+
const newWinner = {
|
|
2047
|
+
...obj,
|
|
2048
|
+
_also_in: [
|
|
2049
|
+
...existing.winner._also_in.filter((a) => a.id !== obj.uuid),
|
|
2050
|
+
{ source: loser._collectionName, id: loser.uuid }
|
|
2051
|
+
]
|
|
2052
|
+
};
|
|
2053
|
+
deduped.add(loser.uuid);
|
|
2054
|
+
deduped.delete(obj.uuid);
|
|
2055
|
+
sourceMap.set(sourceId, { winner: newWinner, index: i });
|
|
2056
|
+
const oldSlot = results.find((r) => r.obj.uuid === loser.uuid);
|
|
2057
|
+
if (oldSlot) {
|
|
2058
|
+
oldSlot.obj = newWinner;
|
|
2059
|
+
oldSlot.index = i;
|
|
2060
|
+
}
|
|
2061
|
+
} else {
|
|
2062
|
+
existing.winner._also_in.push({
|
|
2063
|
+
source: obj._collectionName,
|
|
2064
|
+
id: obj.uuid
|
|
2065
|
+
});
|
|
2066
|
+
deduped.add(obj.uuid);
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
return results.filter((r) => !deduped.has(r.obj.uuid)).map((r) => r.obj);
|
|
2070
|
+
}
|
|
2071
|
+
|
|
1765
2072
|
// node_modules/@prmichaelsen/remember-core/dist/services/preferences.service.js
|
|
1766
2073
|
var PreferencesDatabaseService = class {
|
|
1767
2074
|
logger;
|
|
@@ -2884,212 +3191,6 @@ var RelationshipService = class {
|
|
|
2884
3191
|
// node_modules/@prmichaelsen/remember-core/dist/services/space.service.js
|
|
2885
3192
|
import { Filters as Filters4 } from "weaviate-client";
|
|
2886
3193
|
|
|
2887
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
2888
|
-
import { configure } from "weaviate-client";
|
|
2889
|
-
|
|
2890
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/collection-registry.js
|
|
2891
|
-
async function registerCollection(entry) {
|
|
2892
|
-
const path = getCollectionRegistryPath();
|
|
2893
|
-
await setDocument2(path, entry.collection_name, entry);
|
|
2894
|
-
}
|
|
2895
|
-
|
|
2896
|
-
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/v2-collections.js
|
|
2897
|
-
var collectionCache = /* @__PURE__ */ new Map();
|
|
2898
|
-
var COLLECTION_CACHE_TTL_MS = 6e4;
|
|
2899
|
-
function isCollectionCached(collectionName) {
|
|
2900
|
-
const expiresAt = collectionCache.get(collectionName);
|
|
2901
|
-
if (expiresAt !== void 0 && Date.now() < expiresAt)
|
|
2902
|
-
return true;
|
|
2903
|
-
collectionCache.delete(collectionName);
|
|
2904
|
-
return false;
|
|
2905
|
-
}
|
|
2906
|
-
function cacheCollection(collectionName) {
|
|
2907
|
-
collectionCache.set(collectionName, Date.now() + COLLECTION_CACHE_TTL_MS);
|
|
2908
|
-
}
|
|
2909
|
-
var COMMON_MEMORY_PROPERTIES = [
|
|
2910
|
-
// Core content
|
|
2911
|
-
{ name: "content", dataType: configure.dataType.TEXT },
|
|
2912
|
-
{ name: "content_type", dataType: configure.dataType.TEXT },
|
|
2913
|
-
{ name: "title", dataType: configure.dataType.TEXT },
|
|
2914
|
-
{ name: "summary", dataType: configure.dataType.TEXT },
|
|
2915
|
-
{ name: "type", dataType: configure.dataType.TEXT },
|
|
2916
|
-
// v1 compat (v2: content_type)
|
|
2917
|
-
// Tracking arrays (v2 feature)
|
|
2918
|
-
{ name: "space_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2919
|
-
{ name: "group_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2920
|
-
// Metadata
|
|
2921
|
-
{ name: "created_at", dataType: configure.dataType.DATE },
|
|
2922
|
-
{ name: "updated_at", dataType: configure.dataType.DATE },
|
|
2923
|
-
{ name: "version", dataType: configure.dataType.INT },
|
|
2924
|
-
// User context
|
|
2925
|
-
{ name: "user_id", dataType: configure.dataType.TEXT },
|
|
2926
|
-
// Document type (memory, relationship, comment)
|
|
2927
|
-
{ name: "doc_type", dataType: configure.dataType.TEXT },
|
|
2928
|
-
// Memory-specific fields
|
|
2929
|
-
{ name: "tags", dataType: configure.dataType.TEXT_ARRAY },
|
|
2930
|
-
{ name: "weight", dataType: configure.dataType.NUMBER },
|
|
2931
|
-
{ name: "trust_score", dataType: configure.dataType.NUMBER },
|
|
2932
|
-
{ name: "trust", dataType: configure.dataType.NUMBER },
|
|
2933
|
-
// v1 compat (v2: trust_score)
|
|
2934
|
-
{ name: "base_weight", dataType: configure.dataType.NUMBER },
|
|
2935
|
-
{ name: "computed_weight", dataType: configure.dataType.NUMBER },
|
|
2936
|
-
{ name: "confidence", dataType: configure.dataType.NUMBER },
|
|
2937
|
-
{ name: "strength", dataType: configure.dataType.NUMBER },
|
|
2938
|
-
// Location data (v2 names)
|
|
2939
|
-
{ name: "location_name", dataType: configure.dataType.TEXT },
|
|
2940
|
-
{ name: "location_lat", dataType: configure.dataType.NUMBER },
|
|
2941
|
-
{ name: "location_lon", dataType: configure.dataType.NUMBER },
|
|
2942
|
-
// Location data (v1 compat)
|
|
2943
|
-
{ name: "location_gps_lat", dataType: configure.dataType.NUMBER },
|
|
2944
|
-
{ name: "location_gps_lng", dataType: configure.dataType.NUMBER },
|
|
2945
|
-
{ name: "location_address", dataType: configure.dataType.TEXT },
|
|
2946
|
-
{ name: "location_city", dataType: configure.dataType.TEXT },
|
|
2947
|
-
{ name: "location_country", dataType: configure.dataType.TEXT },
|
|
2948
|
-
{ name: "location_source", dataType: configure.dataType.TEXT },
|
|
2949
|
-
// Locale
|
|
2950
|
-
{ name: "locale_language", dataType: configure.dataType.TEXT },
|
|
2951
|
-
{ name: "locale_timezone", dataType: configure.dataType.TEXT },
|
|
2952
|
-
// Context
|
|
2953
|
-
{ name: "context_app", dataType: configure.dataType.TEXT },
|
|
2954
|
-
{ name: "context_url", dataType: configure.dataType.TEXT },
|
|
2955
|
-
{ name: "context_conversation_id", dataType: configure.dataType.TEXT },
|
|
2956
|
-
{ name: "context_summary", dataType: configure.dataType.TEXT },
|
|
2957
|
-
{ name: "context_timestamp", dataType: configure.dataType.DATE },
|
|
2958
|
-
// Relationships (v2 names)
|
|
2959
|
-
{ name: "relationship_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2960
|
-
{ name: "relationship_type", dataType: configure.dataType.TEXT },
|
|
2961
|
-
{ name: "related_memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2962
|
-
{ name: "observation", dataType: configure.dataType.TEXT },
|
|
2963
|
-
{ name: "source", dataType: configure.dataType.TEXT },
|
|
2964
|
-
// Relationships (v1 compat)
|
|
2965
|
-
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
2966
|
-
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2967
|
-
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
2968
|
-
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
2969
|
-
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
2970
|
-
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
2971
|
-
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
2972
|
-
// Access tracking
|
|
2973
|
-
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
2974
|
-
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
2975
|
-
// References & templates
|
|
2976
|
-
{ name: "references", dataType: configure.dataType.TEXT_ARRAY },
|
|
2977
|
-
{ name: "template_id", dataType: configure.dataType.TEXT },
|
|
2978
|
-
// Comments (Phase 1)
|
|
2979
|
-
{ name: "parent_id", dataType: configure.dataType.TEXT },
|
|
2980
|
-
{ name: "thread_root_id", dataType: configure.dataType.TEXT },
|
|
2981
|
-
{ name: "moderation_flags", dataType: configure.dataType.TEXT_ARRAY },
|
|
2982
|
-
// Agent follow-up tracking
|
|
2983
|
-
{ name: "follow_up_at", dataType: configure.dataType.DATE },
|
|
2984
|
-
// Soft delete
|
|
2985
|
-
{ name: "deleted_at", dataType: configure.dataType.DATE },
|
|
2986
|
-
{ name: "deleted_by", dataType: configure.dataType.TEXT },
|
|
2987
|
-
{ name: "deletion_reason", dataType: configure.dataType.TEXT }
|
|
2988
|
-
];
|
|
2989
|
-
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
2990
|
-
// Publication metadata
|
|
2991
|
-
{ name: "published_at", dataType: configure.dataType.DATE },
|
|
2992
|
-
{ name: "revised_at", dataType: configure.dataType.DATE },
|
|
2993
|
-
// Attribution
|
|
2994
|
-
{ name: "author_id", dataType: configure.dataType.TEXT },
|
|
2995
|
-
{ name: "ghost_id", dataType: configure.dataType.TEXT },
|
|
2996
|
-
{ name: "attribution", dataType: configure.dataType.TEXT },
|
|
2997
|
-
// Discovery
|
|
2998
|
-
{ name: "discovery_count", dataType: configure.dataType.INT },
|
|
2999
|
-
// Revision tracking
|
|
3000
|
-
{ name: "revision_count", dataType: configure.dataType.INT },
|
|
3001
|
-
{ name: "original_memory_id", dataType: configure.dataType.TEXT },
|
|
3002
|
-
// Moderation (nullable — null defaults to approved)
|
|
3003
|
-
{ name: "moderation_status", dataType: configure.dataType.TEXT },
|
|
3004
|
-
{ name: "moderated_by", dataType: configure.dataType.TEXT },
|
|
3005
|
-
{ name: "moderated_at", dataType: configure.dataType.DATE },
|
|
3006
|
-
// Memory-level ACL (nullable — null defaults to owner_only semantics)
|
|
3007
|
-
{ name: "write_mode", dataType: configure.dataType.TEXT },
|
|
3008
|
-
{ name: "owner_id", dataType: configure.dataType.TEXT },
|
|
3009
|
-
{ name: "overwrite_allowed_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
3010
|
-
{ name: "last_revised_by", dataType: configure.dataType.TEXT },
|
|
3011
|
-
// Legacy compatibility (deprecated but kept for migration)
|
|
3012
|
-
{ name: "spaces", dataType: configure.dataType.TEXT_ARRAY },
|
|
3013
|
-
{ name: "space_id", dataType: configure.dataType.TEXT },
|
|
3014
|
-
{ name: "space_memory_id", dataType: configure.dataType.TEXT }
|
|
3015
|
-
];
|
|
3016
|
-
function createSpaceCollectionSchema() {
|
|
3017
|
-
const collectionName = "Memory_spaces_public";
|
|
3018
|
-
return {
|
|
3019
|
-
name: collectionName,
|
|
3020
|
-
description: "Shared memory collection for all public spaces",
|
|
3021
|
-
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
3022
|
-
model: "text-embedding-3-small",
|
|
3023
|
-
dimensions: 1536,
|
|
3024
|
-
vectorizeCollectionName: false
|
|
3025
|
-
}),
|
|
3026
|
-
properties: [
|
|
3027
|
-
...COMMON_MEMORY_PROPERTIES,
|
|
3028
|
-
...PUBLISHED_MEMORY_PROPERTIES
|
|
3029
|
-
],
|
|
3030
|
-
invertedIndex: configure.invertedIndex({
|
|
3031
|
-
indexNullState: true,
|
|
3032
|
-
indexPropertyLength: true,
|
|
3033
|
-
indexTimestamps: true
|
|
3034
|
-
})
|
|
3035
|
-
};
|
|
3036
|
-
}
|
|
3037
|
-
function createGroupCollectionSchema(groupId) {
|
|
3038
|
-
const collectionName = `Memory_groups_${groupId}`;
|
|
3039
|
-
return {
|
|
3040
|
-
name: collectionName,
|
|
3041
|
-
description: `Group memory collection for group: ${groupId}`,
|
|
3042
|
-
vectorizers: configure.vectorizer.text2VecOpenAI({
|
|
3043
|
-
model: "text-embedding-3-small",
|
|
3044
|
-
dimensions: 1536,
|
|
3045
|
-
vectorizeCollectionName: false
|
|
3046
|
-
}),
|
|
3047
|
-
properties: [
|
|
3048
|
-
...COMMON_MEMORY_PROPERTIES,
|
|
3049
|
-
...PUBLISHED_MEMORY_PROPERTIES
|
|
3050
|
-
],
|
|
3051
|
-
invertedIndex: configure.invertedIndex({
|
|
3052
|
-
indexNullState: true,
|
|
3053
|
-
indexPropertyLength: true,
|
|
3054
|
-
indexTimestamps: true
|
|
3055
|
-
})
|
|
3056
|
-
};
|
|
3057
|
-
}
|
|
3058
|
-
async function reconcileCollectionProperties(client2, collectionName, expectedProperties) {
|
|
3059
|
-
const collection = client2.collections.get(collectionName);
|
|
3060
|
-
const config3 = await collection.config.get();
|
|
3061
|
-
const existingNames = new Set(config3.properties.map((p) => p.name));
|
|
3062
|
-
let added = 0;
|
|
3063
|
-
for (const prop of expectedProperties) {
|
|
3064
|
-
if (!existingNames.has(prop.name)) {
|
|
3065
|
-
await collection.config.addProperty(prop);
|
|
3066
|
-
added++;
|
|
3067
|
-
}
|
|
3068
|
-
}
|
|
3069
|
-
return added;
|
|
3070
|
-
}
|
|
3071
|
-
async function ensureGroupCollection(client2, groupId) {
|
|
3072
|
-
const collectionName = `Memory_groups_${groupId}`;
|
|
3073
|
-
if (isCollectionCached(collectionName))
|
|
3074
|
-
return false;
|
|
3075
|
-
const exists = await client2.collections.exists(collectionName);
|
|
3076
|
-
if (exists) {
|
|
3077
|
-
await reconcileCollectionProperties(client2, collectionName, [...COMMON_MEMORY_PROPERTIES, ...PUBLISHED_MEMORY_PROPERTIES]);
|
|
3078
|
-
cacheCollection(collectionName);
|
|
3079
|
-
return false;
|
|
3080
|
-
}
|
|
3081
|
-
const schema = createGroupCollectionSchema(groupId);
|
|
3082
|
-
await client2.collections.create(schema);
|
|
3083
|
-
await registerCollection({
|
|
3084
|
-
collection_name: collectionName,
|
|
3085
|
-
collection_type: "groups",
|
|
3086
|
-
owner_id: groupId,
|
|
3087
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3088
|
-
});
|
|
3089
|
-
cacheCollection(collectionName);
|
|
3090
|
-
return true;
|
|
3091
|
-
}
|
|
3092
|
-
|
|
3093
3194
|
// node_modules/@prmichaelsen/remember-core/dist/database/weaviate/space-schema.js
|
|
3094
3195
|
var PUBLIC_COLLECTION_NAME = "Memory_spaces_public";
|
|
3095
3196
|
function isValidSpaceId(spaceId) {
|
|
@@ -3407,7 +3508,7 @@ var SpaceService = class {
|
|
|
3407
3508
|
}
|
|
3408
3509
|
const combinedFilters = filterList.length > 0 ? Filters4.and(...filterList) : void 0;
|
|
3409
3510
|
const spaceObjects = await this.executeSearch(spacesCollection, input.query, searchType, combinedFilters, fetchLimit);
|
|
3410
|
-
allObjects.push(...spaceObjects);
|
|
3511
|
+
allObjects.push(...tagWithSource(spaceObjects, spacesCollectionName));
|
|
3411
3512
|
}
|
|
3412
3513
|
for (const groupId of groups) {
|
|
3413
3514
|
const groupCollectionName = getCollectionName(CollectionType.GROUPS, groupId);
|
|
@@ -3418,24 +3519,26 @@ var SpaceService = class {
|
|
|
3418
3519
|
const filterList = this.buildBaseFilters(groupCollection, input);
|
|
3419
3520
|
const combinedFilters = filterList.length > 0 ? Filters4.and(...filterList) : void 0;
|
|
3420
3521
|
const groupObjects = await this.executeSearch(groupCollection, input.query, searchType, combinedFilters, fetchLimit);
|
|
3421
|
-
allObjects.push(...groupObjects);
|
|
3522
|
+
allObjects.push(...tagWithSource(groupObjects, groupCollectionName));
|
|
3422
3523
|
}
|
|
3423
3524
|
const seen = /* @__PURE__ */ new Set();
|
|
3424
|
-
const
|
|
3525
|
+
const uuidDeduped = allObjects.filter((obj) => {
|
|
3425
3526
|
if (seen.has(obj.uuid))
|
|
3426
3527
|
return false;
|
|
3427
3528
|
seen.add(obj.uuid);
|
|
3428
3529
|
return true;
|
|
3429
3530
|
});
|
|
3430
|
-
|
|
3531
|
+
const contentDeduped = dedupeBySourceId(uuidDeduped, input.dedupe);
|
|
3532
|
+
contentDeduped.sort((a, b) => {
|
|
3431
3533
|
const scoreA = a.metadata?.score ?? 0;
|
|
3432
3534
|
const scoreB = b.metadata?.score ?? 0;
|
|
3433
3535
|
return scoreB - scoreA;
|
|
3434
3536
|
});
|
|
3435
|
-
const paginated =
|
|
3537
|
+
const paginated = contentDeduped.slice(offset, offset + limit);
|
|
3436
3538
|
const memories = paginated.map((obj) => ({
|
|
3437
3539
|
id: obj.uuid,
|
|
3438
|
-
...obj.properties
|
|
3540
|
+
...obj.properties,
|
|
3541
|
+
...obj._also_in?.length ? { also_in: obj._also_in } : {}
|
|
3439
3542
|
}));
|
|
3440
3543
|
const isAllPublic = spaces.length === 0 && groups.length === 0;
|
|
3441
3544
|
return {
|
|
@@ -3554,7 +3657,8 @@ var SpaceService = class {
|
|
|
3554
3657
|
discovery_count: 0,
|
|
3555
3658
|
attribution: "user",
|
|
3556
3659
|
moderation_status: spaceModerationStatus,
|
|
3557
|
-
tags: mergedTags
|
|
3660
|
+
tags: mergedTags,
|
|
3661
|
+
original_memory_id: request.payload.memory_id
|
|
3558
3662
|
};
|
|
3559
3663
|
delete publishedMemory._additional;
|
|
3560
3664
|
if (existingSpaceMemory) {
|
|
@@ -3595,7 +3699,8 @@ var SpaceService = class {
|
|
|
3595
3699
|
discovery_count: 0,
|
|
3596
3700
|
attribution: "user",
|
|
3597
3701
|
moderation_status: groupModerationStatus,
|
|
3598
|
-
tags: mergedTags
|
|
3702
|
+
tags: mergedTags,
|
|
3703
|
+
original_memory_id: request.payload.memory_id
|
|
3599
3704
|
};
|
|
3600
3705
|
delete groupMemory._additional;
|
|
3601
3706
|
if (existingGroupMemory) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prmichaelsen/remember-mcp",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.1",
|
|
4
4
|
"description": "Multi-tenant memory system MCP server with vector search and relationships",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
51
51
|
"@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
|
|
52
52
|
"@prmichaelsen/mcp-auth": "^7.0.4",
|
|
53
|
-
"@prmichaelsen/remember-core": "^0.33.
|
|
53
|
+
"@prmichaelsen/remember-core": "^0.33.3",
|
|
54
54
|
"dotenv": "^16.4.5",
|
|
55
55
|
"uuid": "^13.0.0",
|
|
56
56
|
"weaviate-client": "^3.2.0"
|