@anuma/sdk 6.21.1 → 6.22.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/dist/expo/{chunk-CIMZZ7GQ.mjs → chunk-6BULYLRY.mjs} +92 -8
- package/dist/expo/index.cjs +761 -162
- package/dist/expo/index.d.mts +151 -9
- package/dist/expo/index.d.ts +151 -9
- package/dist/expo/index.mjs +516 -14
- package/dist/{react/recall-7Q3V337H.mjs → expo/recall-CUTJWQDQ.mjs} +1 -1
- package/dist/memory/context.cjs +183 -0
- package/dist/memory/context.d.mts +936 -0
- package/dist/memory/context.d.ts +936 -0
- package/dist/memory/context.mjs +157 -0
- package/dist/react/{chunk-AVYB5IXC.mjs → chunk-GPLMMMZN.mjs} +1 -1
- package/dist/react/{chunk-JRVAUZHM.mjs → chunk-K4N52PSK.mjs} +93 -9
- package/dist/react/{consolidate-URHGJT7I.mjs → consolidate-XKS6IZFC.mjs} +2 -2
- package/dist/react/index.cjs +876 -270
- package/dist/react/index.d.mts +209 -9
- package/dist/react/index.d.ts +209 -9
- package/dist/react/index.mjs +569 -65
- package/dist/{expo/recall-FQQGE6A2.mjs → react/recall-LFHIWONV.mjs} +2 -2
- package/dist/server/{chunk-4DSDATYG.mjs → chunk-FEDRFVHD.mjs} +182 -98
- package/dist/server/index.cjs +815 -216
- package/dist/server/index.d.mts +150 -5
- package/dist/server/index.d.ts +150 -5
- package/dist/server/index.mjs +509 -7
- package/dist/server/{recall-HA4UX4BB.mjs → recall-Z2WJGXOL.mjs} +1 -1
- package/dist/telemetry/index.d.mts +7 -1
- package/dist/telemetry/index.d.ts +7 -1
- package/package.json +8 -1
- package/dist/react/{chunk-WUG6GTHO.mjs → chunk-MHZB6KIX.mjs} +8 -8
package/dist/expo/index.cjs
CHANGED
|
@@ -1199,6 +1199,18 @@ var init_encryption_utils = __esm({
|
|
|
1199
1199
|
}
|
|
1200
1200
|
});
|
|
1201
1201
|
|
|
1202
|
+
// src/lib/db/extractionJobs/models.ts
|
|
1203
|
+
var import_watermelondb, ExtractionJob;
|
|
1204
|
+
var init_models = __esm({
|
|
1205
|
+
"src/lib/db/extractionJobs/models.ts"() {
|
|
1206
|
+
"use strict";
|
|
1207
|
+
import_watermelondb = require("@nozbe/watermelondb");
|
|
1208
|
+
ExtractionJob = class extends import_watermelondb.Model {
|
|
1209
|
+
};
|
|
1210
|
+
ExtractionJob.table = "memory_extraction_jobs";
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1202
1214
|
// src/lib/db/chat/conversationEncryption.ts
|
|
1203
1215
|
async function encryptConversationFields(conversation, address, signMessage, embeddedWalletSigner) {
|
|
1204
1216
|
if (!address || !signMessage) {
|
|
@@ -1786,7 +1798,7 @@ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation"
|
|
|
1786
1798
|
);
|
|
1787
1799
|
}
|
|
1788
1800
|
async function getConversationOp(ctx, id) {
|
|
1789
|
-
const results = await ctx.conversationsCollection.query(
|
|
1801
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("conversation_id", id), import_watermelondb2.Q.where("is_deleted", false)).fetch();
|
|
1790
1802
|
return results.length > 0 ? await conversationToStored(
|
|
1791
1803
|
results[0],
|
|
1792
1804
|
ctx.walletAddress,
|
|
@@ -1795,7 +1807,7 @@ async function getConversationOp(ctx, id) {
|
|
|
1795
1807
|
) : null;
|
|
1796
1808
|
}
|
|
1797
1809
|
async function getConversationsOp(ctx) {
|
|
1798
|
-
const results = await ctx.conversationsCollection.query(
|
|
1810
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("is_deleted", false), import_watermelondb2.Q.sortBy("created_at", import_watermelondb2.Q.desc)).unsafeFetchRaw();
|
|
1799
1811
|
return Promise.all(
|
|
1800
1812
|
results.map(
|
|
1801
1813
|
(raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -1816,33 +1828,33 @@ function conversationRawToLazyStored(raw) {
|
|
|
1816
1828
|
};
|
|
1817
1829
|
}
|
|
1818
1830
|
async function getConversationsLazyOp(ctx) {
|
|
1819
|
-
const results = await ctx.conversationsCollection.query(
|
|
1831
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("is_deleted", false), import_watermelondb2.Q.sortBy("created_at", import_watermelondb2.Q.desc)).unsafeFetchRaw();
|
|
1820
1832
|
return results.map(conversationRawToLazyStored);
|
|
1821
1833
|
}
|
|
1822
1834
|
async function getConversationsPageOp(ctx, options) {
|
|
1823
1835
|
const limit = Math.floor(options?.limit ?? 200);
|
|
1824
1836
|
if (!Number.isFinite(limit) || limit < 1) return [];
|
|
1825
1837
|
const exclude = new Set(options?.boundaryExcludeUniqueIds ?? []);
|
|
1826
|
-
const clauses = [
|
|
1838
|
+
const clauses = [import_watermelondb2.Q.where("is_deleted", false)];
|
|
1827
1839
|
if (options?.before !== void 0) {
|
|
1828
1840
|
clauses.push(
|
|
1829
|
-
exclude.size > 0 ?
|
|
1841
|
+
exclude.size > 0 ? import_watermelondb2.Q.where("created_at", import_watermelondb2.Q.lte(options.before)) : import_watermelondb2.Q.where("created_at", import_watermelondb2.Q.lt(options.before))
|
|
1830
1842
|
);
|
|
1831
1843
|
}
|
|
1832
|
-
const fetched = await ctx.conversationsCollection.query(...clauses,
|
|
1844
|
+
const fetched = await ctx.conversationsCollection.query(...clauses, import_watermelondb2.Q.sortBy("created_at", import_watermelondb2.Q.desc), import_watermelondb2.Q.take(limit + exclude.size)).unsafeFetchRaw();
|
|
1833
1845
|
const results = exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched;
|
|
1834
1846
|
return results.slice(0, limit).map(conversationRawToLazyStored);
|
|
1835
1847
|
}
|
|
1836
1848
|
async function getConversationsByProjectLazyOp(ctx, projectId) {
|
|
1837
1849
|
const results = await ctx.conversationsCollection.query(
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1850
|
+
import_watermelondb2.Q.where("project_id", projectId === null ? "" : projectId),
|
|
1851
|
+
import_watermelondb2.Q.where("is_deleted", false),
|
|
1852
|
+
import_watermelondb2.Q.sortBy("created_at", import_watermelondb2.Q.desc)
|
|
1841
1853
|
).unsafeFetchRaw();
|
|
1842
1854
|
return results.map(conversationRawToLazyStored);
|
|
1843
1855
|
}
|
|
1844
1856
|
async function updateConversationTitleOp(ctx, id, title) {
|
|
1845
|
-
const results = await ctx.conversationsCollection.query(
|
|
1857
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("conversation_id", id), import_watermelondb2.Q.where("is_deleted", false)).fetch();
|
|
1846
1858
|
if (results.length > 0) {
|
|
1847
1859
|
const encryptedOpts = ctx.walletAddress && ctx.signMessage ? await encryptConversationFields(
|
|
1848
1860
|
{ title },
|
|
@@ -1861,19 +1873,21 @@ async function updateConversationTitleOp(ctx, id, title) {
|
|
|
1861
1873
|
return false;
|
|
1862
1874
|
}
|
|
1863
1875
|
async function deleteConversationOp(ctx, id) {
|
|
1864
|
-
const results = await ctx.conversationsCollection.query(
|
|
1876
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("conversation_id", id), import_watermelondb2.Q.where("is_deleted", false)).fetch();
|
|
1865
1877
|
if (results.length > 0) {
|
|
1866
1878
|
await ctx.database.write(async () => {
|
|
1867
1879
|
await results[0].update((conv) => {
|
|
1868
1880
|
conv._setRaw("is_deleted", true);
|
|
1869
1881
|
});
|
|
1882
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb2.Q.where("conversation_id", id)).fetch() : [];
|
|
1883
|
+
for (const job of jobs) await job.destroyPermanently();
|
|
1870
1884
|
});
|
|
1871
1885
|
return true;
|
|
1872
1886
|
}
|
|
1873
1887
|
return false;
|
|
1874
1888
|
}
|
|
1875
1889
|
async function updateConversationPinnedOp(ctx, id, pinned) {
|
|
1876
|
-
const results = await ctx.conversationsCollection.query(
|
|
1890
|
+
const results = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("conversation_id", id), import_watermelondb2.Q.where("is_deleted", false)).fetch();
|
|
1877
1891
|
if (results.length > 0) {
|
|
1878
1892
|
await ctx.database.write(async () => {
|
|
1879
1893
|
await results[0].update((conv) => {
|
|
@@ -1885,7 +1899,7 @@ async function updateConversationPinnedOp(ctx, id, pinned) {
|
|
|
1885
1899
|
return false;
|
|
1886
1900
|
}
|
|
1887
1901
|
async function getMessagesOp(ctx, convId) {
|
|
1888
|
-
const results = await ctx.messagesCollection.query(
|
|
1902
|
+
const results = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId), import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.asc)).unsafeFetchRaw();
|
|
1889
1903
|
return Promise.all(
|
|
1890
1904
|
results.map(
|
|
1891
1905
|
(raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -1893,19 +1907,19 @@ async function getMessagesOp(ctx, convId) {
|
|
|
1893
1907
|
);
|
|
1894
1908
|
}
|
|
1895
1909
|
async function getMessageCountOp(ctx, convId) {
|
|
1896
|
-
return await ctx.messagesCollection.query(
|
|
1910
|
+
return await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId)).fetchCount();
|
|
1897
1911
|
}
|
|
1898
1912
|
async function getMessagesPageOp(ctx, convId, opts) {
|
|
1899
1913
|
const limit = Math.floor(opts.limit);
|
|
1900
1914
|
if (!Number.isFinite(limit) || limit < 1) return [];
|
|
1901
1915
|
const exclude = new Set(opts.boundaryExcludeUniqueIds ?? []);
|
|
1902
|
-
const clauses = [
|
|
1916
|
+
const clauses = [import_watermelondb2.Q.where("conversation_id", convId)];
|
|
1903
1917
|
if (opts.beforeMessageId !== void 0) {
|
|
1904
1918
|
clauses.push(
|
|
1905
|
-
exclude.size > 0 ?
|
|
1919
|
+
exclude.size > 0 ? import_watermelondb2.Q.where("message_id", import_watermelondb2.Q.lte(opts.beforeMessageId)) : import_watermelondb2.Q.where("message_id", import_watermelondb2.Q.lt(opts.beforeMessageId))
|
|
1906
1920
|
);
|
|
1907
1921
|
}
|
|
1908
|
-
const fetched = await ctx.messagesCollection.query(...clauses,
|
|
1922
|
+
const fetched = await ctx.messagesCollection.query(...clauses, import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.desc), import_watermelondb2.Q.take(limit + exclude.size)).unsafeFetchRaw();
|
|
1909
1923
|
const results = (exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched).slice(0, limit);
|
|
1910
1924
|
results.reverse();
|
|
1911
1925
|
return Promise.all(
|
|
@@ -1917,7 +1931,7 @@ async function getMessagesPageOp(ctx, convId, opts) {
|
|
|
1917
1931
|
);
|
|
1918
1932
|
}
|
|
1919
1933
|
async function getMessageSkeletonsOp(ctx, convId) {
|
|
1920
|
-
const results = await ctx.messagesCollection.query(
|
|
1934
|
+
const results = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId), import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.asc)).unsafeFetchRaw();
|
|
1921
1935
|
const roleById = /* @__PURE__ */ new Map();
|
|
1922
1936
|
for (const raw of results) {
|
|
1923
1937
|
roleById.set(raw.id, raw.role);
|
|
@@ -1964,7 +1978,7 @@ async function getMessageSkeletonsOp(ctx, convId) {
|
|
|
1964
1978
|
return skeletons;
|
|
1965
1979
|
}
|
|
1966
1980
|
async function getToolCallEventIdsOp(ctx, convId) {
|
|
1967
|
-
const results = await ctx.messagesCollection.query(
|
|
1981
|
+
const results = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId)).unsafeFetchRaw();
|
|
1968
1982
|
const ids = /* @__PURE__ */ new Set();
|
|
1969
1983
|
for (const raw of results) {
|
|
1970
1984
|
const value = raw.tool_call_events;
|
|
@@ -1987,8 +2001,16 @@ async function getToolCallEventIdsOp(ctx, convId) {
|
|
|
1987
2001
|
return ids;
|
|
1988
2002
|
}
|
|
1989
2003
|
async function clearMessagesOp(ctx, convId) {
|
|
1990
|
-
const messages = await ctx.messagesCollection.query(import_watermelondb.Q.where("conversation_id", convId)).fetch();
|
|
1991
2004
|
await ctx.database.write(async () => {
|
|
2005
|
+
const messages = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId)).fetch();
|
|
2006
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb2.Q.where("conversation_id", convId)).fetch() : [];
|
|
2007
|
+
for (const job of jobs) {
|
|
2008
|
+
await job.update((row) => {
|
|
2009
|
+
row._setRaw("message_ids", "[]");
|
|
2010
|
+
row._setRaw("watermark", null);
|
|
2011
|
+
row._setRaw("watermark_seq", null);
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
1992
2014
|
for (const message of messages) {
|
|
1993
2015
|
await message.update((msg) => {
|
|
1994
2016
|
msg._setRaw("file_ids", null);
|
|
@@ -1998,6 +2020,30 @@ async function clearMessagesOp(ctx, convId) {
|
|
|
1998
2020
|
}
|
|
1999
2021
|
});
|
|
2000
2022
|
}
|
|
2023
|
+
async function deleteMessageOp(ctx, uniqueId) {
|
|
2024
|
+
let message;
|
|
2025
|
+
try {
|
|
2026
|
+
message = await ctx.messagesCollection.find(uniqueId);
|
|
2027
|
+
} catch {
|
|
2028
|
+
return null;
|
|
2029
|
+
}
|
|
2030
|
+
await ctx.database.write(async () => {
|
|
2031
|
+
const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb2.Q.where("conversation_id", message.conversationId)).fetch() : [];
|
|
2032
|
+
for (const job of jobs) {
|
|
2033
|
+
const ids = JSON.parse(String(job._getRaw("message_ids")));
|
|
2034
|
+
await job.update((row) => {
|
|
2035
|
+
row._setRaw("message_ids", JSON.stringify(ids.filter((id) => id !== uniqueId)));
|
|
2036
|
+
if (row._getRaw("watermark") === uniqueId) row._setRaw("watermark", null);
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
await message.update((msg) => {
|
|
2040
|
+
msg._setRaw("file_ids", null);
|
|
2041
|
+
msg._setRaw("files", null);
|
|
2042
|
+
});
|
|
2043
|
+
await message.destroyPermanently();
|
|
2044
|
+
});
|
|
2045
|
+
return uniqueId;
|
|
2046
|
+
}
|
|
2001
2047
|
async function encryptMessageOptsIfNeeded(ctx, opts) {
|
|
2002
2048
|
return ctx.walletAddress && ctx.signMessage ? await encryptMessageFields(opts, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : opts;
|
|
2003
2049
|
}
|
|
@@ -2055,9 +2101,9 @@ async function createMessageOp(ctx, opts) {
|
|
|
2055
2101
|
}
|
|
2056
2102
|
}
|
|
2057
2103
|
const newest = await ctx.messagesCollection.query(
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2104
|
+
import_watermelondb2.Q.where("conversation_id", opts.conversationId),
|
|
2105
|
+
import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.desc),
|
|
2106
|
+
import_watermelondb2.Q.take(1)
|
|
2061
2107
|
).fetch();
|
|
2062
2108
|
const messageId = (newest[0]?.messageId ?? 0) + 1;
|
|
2063
2109
|
const encryptedOpts = await encryptMessageOptsIfNeeded(ctx, opts);
|
|
@@ -2071,7 +2117,7 @@ async function createMessageOp(ctx, opts) {
|
|
|
2071
2117
|
return messageToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
2072
2118
|
}
|
|
2073
2119
|
async function upsertMessageOp(ctx, opts) {
|
|
2074
|
-
const results = await ctx.messagesCollection.query(
|
|
2120
|
+
const results = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", opts.uniqueId)).fetch();
|
|
2075
2121
|
const existing = results.length > 0 ? results[0] : null;
|
|
2076
2122
|
if (!existing) {
|
|
2077
2123
|
return createMessageOp(ctx, opts);
|
|
@@ -2244,12 +2290,12 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
2244
2290
|
embeddingModel,
|
|
2245
2291
|
chunkCache
|
|
2246
2292
|
} = options || {};
|
|
2247
|
-
const activeConversations = await ctx.conversationsCollection.query(
|
|
2293
|
+
const activeConversations = await ctx.conversationsCollection.query(import_watermelondb2.Q.where("is_deleted", false)).fetch();
|
|
2248
2294
|
const activeConversationIds = new Set(
|
|
2249
2295
|
// Use _getRaw for reliable raw column access
|
|
2250
2296
|
activeConversations.map((c) => String(c._getRaw("conversation_id")))
|
|
2251
2297
|
);
|
|
2252
|
-
const queryConditions = conversationId ? [
|
|
2298
|
+
const queryConditions = conversationId ? [import_watermelondb2.Q.where("conversation_id", conversationId)] : [];
|
|
2253
2299
|
const messages = await ctx.messagesCollection.query(...queryConditions).unsafeFetchRaw();
|
|
2254
2300
|
const candidates = [];
|
|
2255
2301
|
let staleSkipped = 0;
|
|
@@ -2413,17 +2459,18 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
|
|
|
2413
2459
|
isDeleted: false
|
|
2414
2460
|
};
|
|
2415
2461
|
}
|
|
2416
|
-
var
|
|
2462
|
+
var import_watermelondb2, import_uuid2;
|
|
2417
2463
|
var init_operations = __esm({
|
|
2418
2464
|
"src/lib/db/chat/operations.ts"() {
|
|
2419
2465
|
"use strict";
|
|
2420
|
-
|
|
2466
|
+
import_watermelondb2 = require("@nozbe/watermelondb");
|
|
2421
2467
|
import_uuid2 = require("uuid");
|
|
2422
2468
|
init_useEncryption();
|
|
2423
2469
|
init_logger();
|
|
2424
2470
|
init_vector();
|
|
2425
2471
|
init_vectorEncoding();
|
|
2426
2472
|
init_encryption_utils();
|
|
2473
|
+
init_models();
|
|
2427
2474
|
init_conversationEncryption();
|
|
2428
2475
|
init_encryption();
|
|
2429
2476
|
init_types2();
|
|
@@ -4695,7 +4742,7 @@ async function upsertEntitiesInWrite(ctx, entities) {
|
|
|
4695
4742
|
const unique = Array.from(kindByName.keys());
|
|
4696
4743
|
const out = /* @__PURE__ */ new Map();
|
|
4697
4744
|
if (unique.length === 0) return { entities: out, operations: [], kindBackfills: [] };
|
|
4698
|
-
const existing = await ctx.entityCollection.query(
|
|
4745
|
+
const existing = await ctx.entityCollection.query(import_watermelondb9.Q.where("canonical_name", import_watermelondb9.Q.oneOf(unique))).fetch();
|
|
4699
4746
|
const existingNames = new Set(existing.map((e) => e.canonicalName));
|
|
4700
4747
|
const kindBackfills = existing.filter((e) => {
|
|
4701
4748
|
const incoming = kindByName.get(e.canonicalName);
|
|
@@ -4725,7 +4772,7 @@ function prepareKindBackfills(backfills) {
|
|
|
4725
4772
|
}
|
|
4726
4773
|
async function findVaultRowInWrite(ctx, memoryId) {
|
|
4727
4774
|
try {
|
|
4728
|
-
const rows = await ctx.database.get("memory_vault").query(
|
|
4775
|
+
const rows = await ctx.database.get("memory_vault").query(import_watermelondb9.Q.where("id", memoryId)).fetch();
|
|
4729
4776
|
return rows[0] ?? null;
|
|
4730
4777
|
} catch {
|
|
4731
4778
|
return null;
|
|
@@ -4800,7 +4847,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
4800
4847
|
return;
|
|
4801
4848
|
}
|
|
4802
4849
|
if (entities.length === 0) return;
|
|
4803
|
-
const existingLinks = await ctx.memoryEntityCollection.query(
|
|
4850
|
+
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("memory_id", memoryId)).fetch();
|
|
4804
4851
|
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
4805
4852
|
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
4806
4853
|
const keptIds = entities.map((e) => e.uniqueId);
|
|
@@ -4835,7 +4882,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
4835
4882
|
}
|
|
4836
4883
|
async function resolveEntitiesByIds(ctx, entityIds) {
|
|
4837
4884
|
if (entityIds.length === 0) return [];
|
|
4838
|
-
const rows = await ctx.entityCollection.query(
|
|
4885
|
+
const rows = await ctx.entityCollection.query(import_watermelondb9.Q.where("id", import_watermelondb9.Q.oneOf(Array.from(entityIds)))).fetch();
|
|
4839
4886
|
return rows.map(entityToStored);
|
|
4840
4887
|
}
|
|
4841
4888
|
function autoLinkBlocked(row) {
|
|
@@ -4870,7 +4917,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
4870
4917
|
kindBackfills
|
|
4871
4918
|
} = await upsertEntitiesInWrite(ctx, normalized);
|
|
4872
4919
|
entities = Array.from(byName.values());
|
|
4873
|
-
const existingLinks = await ctx.memoryEntityCollection.query(
|
|
4920
|
+
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("memory_id", memoryId)).fetch();
|
|
4874
4921
|
const keep = new Set(entities.map((e) => e.uniqueId));
|
|
4875
4922
|
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
4876
4923
|
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
@@ -4905,17 +4952,17 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
4905
4952
|
async function findOrphanedEntities(ctx, memoryId, toDestroy) {
|
|
4906
4953
|
const candidateIds = [...new Set(toDestroy.map((l) => String(l.entityId)))];
|
|
4907
4954
|
if (candidateIds.length === 0) return [];
|
|
4908
|
-
const links = await ctx.memoryEntityCollection.query(
|
|
4955
|
+
const links = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("entity_id", import_watermelondb9.Q.oneOf(candidateIds))).fetch();
|
|
4909
4956
|
const stillLinked = new Set(
|
|
4910
4957
|
links.filter((l) => String(l.memoryId) !== memoryId).map((l) => String(l.entityId))
|
|
4911
4958
|
);
|
|
4912
4959
|
const orphanIds = candidateIds.filter((id) => !stillLinked.has(id));
|
|
4913
4960
|
if (orphanIds.length === 0) return [];
|
|
4914
|
-
return await ctx.entityCollection.query(
|
|
4961
|
+
return await ctx.entityCollection.query(import_watermelondb9.Q.where("id", import_watermelondb9.Q.oneOf(orphanIds))).fetch();
|
|
4915
4962
|
}
|
|
4916
4963
|
async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
4917
4964
|
if (memoryIds.length === 0) return;
|
|
4918
|
-
const links = await ctx.memoryEntityCollection.query(
|
|
4965
|
+
const links = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("memory_id", import_watermelondb9.Q.oneOf(Array.from(memoryIds)))).fetch();
|
|
4919
4966
|
if (links.length === 0) return;
|
|
4920
4967
|
await ctx.database.write(async () => {
|
|
4921
4968
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
@@ -4923,7 +4970,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
4923
4970
|
}
|
|
4924
4971
|
async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
4925
4972
|
if (!userId) return;
|
|
4926
|
-
const links = await ctx.memoryEntityCollection.query(
|
|
4973
|
+
const links = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("user_id", userId)).fetch();
|
|
4927
4974
|
if (links.length === 0) return;
|
|
4928
4975
|
await ctx.database.write(async () => {
|
|
4929
4976
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
@@ -4932,15 +4979,15 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
4932
4979
|
async function getMemoriesByEntityNamesOp(ctx, entityNames) {
|
|
4933
4980
|
const unique = Array.from(new Set(entityNames.map(normalizeEntityName).filter((n) => n.length > 0)));
|
|
4934
4981
|
if (unique.length === 0) return /* @__PURE__ */ new Map();
|
|
4935
|
-
const entityRows = await ctx.entityCollection.query(
|
|
4982
|
+
const entityRows = await ctx.entityCollection.query(import_watermelondb9.Q.where("canonical_name", import_watermelondb9.Q.oneOf(unique))).fetch();
|
|
4936
4983
|
if (entityRows.length === 0) return /* @__PURE__ */ new Map();
|
|
4937
4984
|
const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
|
|
4938
|
-
const linkConditions = [
|
|
4985
|
+
const linkConditions = [import_watermelondb9.Q.where("entity_id", import_watermelondb9.Q.oneOf(entityRows.map((e) => e.id)))];
|
|
4939
4986
|
if (ctx.userId !== void 0) {
|
|
4940
4987
|
if (ctx.allowUnscopedRows) {
|
|
4941
|
-
linkConditions.push(
|
|
4988
|
+
linkConditions.push(import_watermelondb9.Q.or(import_watermelondb9.Q.where("user_id", ctx.userId), import_watermelondb9.Q.where("user_id", null)));
|
|
4942
4989
|
} else {
|
|
4943
|
-
linkConditions.push(
|
|
4990
|
+
linkConditions.push(import_watermelondb9.Q.where("user_id", ctx.userId));
|
|
4944
4991
|
}
|
|
4945
4992
|
}
|
|
4946
4993
|
const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
|
|
@@ -4961,18 +5008,18 @@ async function getMemoriesByEntityNamesOp(ctx, entityNames) {
|
|
|
4961
5008
|
async function getEntitiesByMemoryIdsOp(ctx, memoryIds) {
|
|
4962
5009
|
const unique = Array.from(new Set(memoryIds.filter((id) => id.length > 0)));
|
|
4963
5010
|
if (unique.length === 0) return /* @__PURE__ */ new Map();
|
|
4964
|
-
const linkConditions = [
|
|
5011
|
+
const linkConditions = [import_watermelondb9.Q.where("memory_id", import_watermelondb9.Q.oneOf(unique))];
|
|
4965
5012
|
if (ctx.userId !== void 0) {
|
|
4966
5013
|
if (ctx.allowUnscopedRows) {
|
|
4967
|
-
linkConditions.push(
|
|
5014
|
+
linkConditions.push(import_watermelondb9.Q.or(import_watermelondb9.Q.where("user_id", ctx.userId), import_watermelondb9.Q.where("user_id", null)));
|
|
4968
5015
|
} else {
|
|
4969
|
-
linkConditions.push(
|
|
5016
|
+
linkConditions.push(import_watermelondb9.Q.where("user_id", ctx.userId));
|
|
4970
5017
|
}
|
|
4971
5018
|
}
|
|
4972
5019
|
const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
|
|
4973
5020
|
if (links.length === 0) return /* @__PURE__ */ new Map();
|
|
4974
5021
|
const entityIds = Array.from(new Set(links.map((l) => String(l.entityId))));
|
|
4975
|
-
const entityRows = await ctx.entityCollection.query(
|
|
5022
|
+
const entityRows = await ctx.entityCollection.query(import_watermelondb9.Q.where("id", import_watermelondb9.Q.oneOf(entityIds))).fetch();
|
|
4976
5023
|
const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
|
|
4977
5024
|
const out = /* @__PURE__ */ new Map();
|
|
4978
5025
|
for (const link of links) {
|
|
@@ -4988,11 +5035,11 @@ async function getEntitiesByMemoryIdsOp(ctx, memoryIds) {
|
|
|
4988
5035
|
}
|
|
4989
5036
|
return out;
|
|
4990
5037
|
}
|
|
4991
|
-
var
|
|
5038
|
+
var import_watermelondb9;
|
|
4992
5039
|
var init_operations2 = __esm({
|
|
4993
5040
|
"src/lib/db/entities/operations.ts"() {
|
|
4994
5041
|
"use strict";
|
|
4995
|
-
|
|
5042
|
+
import_watermelondb9 = require("@nozbe/watermelondb");
|
|
4996
5043
|
init_types3();
|
|
4997
5044
|
}
|
|
4998
5045
|
});
|
|
@@ -5059,23 +5106,24 @@ function visibilityOrPrivate(value) {
|
|
|
5059
5106
|
function visibilityConditions(requested) {
|
|
5060
5107
|
if (!requested?.length) return [];
|
|
5061
5108
|
if (!requested.includes("private")) {
|
|
5062
|
-
return [
|
|
5109
|
+
return [import_watermelondb10.Q.where("visibility", import_watermelondb10.Q.oneOf([...requested]))];
|
|
5063
5110
|
}
|
|
5064
5111
|
const excluded = NON_PRIVATE_VISIBILITIES.filter((v) => !requested.includes(v));
|
|
5065
5112
|
if (excluded.length === 0) return [];
|
|
5066
|
-
return [
|
|
5113
|
+
return [import_watermelondb10.Q.or(import_watermelondb10.Q.where("visibility", null), import_watermelondb10.Q.where("visibility", import_watermelondb10.Q.notIn(excluded)))];
|
|
5067
5114
|
}
|
|
5068
5115
|
function isOwnedByCtxUser(ctx, record) {
|
|
5069
5116
|
return ctx.userId === void 0 || record.userId === ctx.userId;
|
|
5070
5117
|
}
|
|
5071
5118
|
function baseVaultConditions(ctx, options) {
|
|
5072
5119
|
return [
|
|
5073
|
-
...options?.
|
|
5074
|
-
...options?.
|
|
5075
|
-
...options?.
|
|
5076
|
-
...options?.
|
|
5077
|
-
...
|
|
5078
|
-
...
|
|
5120
|
+
...options?.memoryIds !== void 0 ? [import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(options.memoryIds))] : [],
|
|
5121
|
+
...options?.includeDeleted ? [] : [import_watermelondb10.Q.where("is_deleted", false)],
|
|
5122
|
+
...options?.includeArchived ? [] : [import_watermelondb10.Q.where("archived_at", import_watermelondb10.Q.eq(null))],
|
|
5123
|
+
...options?.includeQuarantined ? [] : [import_watermelondb10.Q.where("trust_tier", import_watermelondb10.Q.notEq("quarantined"))],
|
|
5124
|
+
...options?.includeSuperseded ? [] : [import_watermelondb10.Q.where("superseded_by", null)],
|
|
5125
|
+
...ctx.userId !== void 0 ? [import_watermelondb10.Q.where("user_id", ctx.userId)] : [],
|
|
5126
|
+
...options?.since ? [import_watermelondb10.Q.where("updated_at", import_watermelondb10.Q.gt(options.since.getTime()))] : []
|
|
5079
5127
|
];
|
|
5080
5128
|
}
|
|
5081
5129
|
function normalizeTrustTier(value) {
|
|
@@ -5153,6 +5201,8 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
5153
5201
|
ctx.embeddedWalletSigner
|
|
5154
5202
|
) : opts.content;
|
|
5155
5203
|
const created = await ctx.database.write(async () => {
|
|
5204
|
+
if (ctx.canWrite && !await ctx.canWrite())
|
|
5205
|
+
throw new Error("Memory source is no longer eligible");
|
|
5156
5206
|
return ctx.vaultMemoryCollection.create((record) => {
|
|
5157
5207
|
record._setRaw("content", encryptedContent);
|
|
5158
5208
|
record._setRaw("scope", scope);
|
|
@@ -5202,6 +5252,8 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
5202
5252
|
) : opts.content;
|
|
5203
5253
|
let createdRecord = null;
|
|
5204
5254
|
await ctx.database.write(async () => {
|
|
5255
|
+
if (ctx.canWrite && !await ctx.canWrite())
|
|
5256
|
+
throw new Error("Memory source is no longer eligible");
|
|
5205
5257
|
let target;
|
|
5206
5258
|
try {
|
|
5207
5259
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -5247,11 +5299,11 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
5247
5299
|
async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
|
|
5248
5300
|
const records = await ctx.vaultMemoryCollection.query(
|
|
5249
5301
|
...baseVaultConditions(ctx),
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5302
|
+
import_watermelondb10.Q.where("event_time_start", import_watermelondb10.Q.notEq(null)),
|
|
5303
|
+
import_watermelondb10.Q.where("event_time_start", import_watermelondb10.Q.lte(windowEnd)),
|
|
5304
|
+
import_watermelondb10.Q.or(
|
|
5305
|
+
import_watermelondb10.Q.where("event_time_start", import_watermelondb10.Q.gte(windowStart)),
|
|
5306
|
+
import_watermelondb10.Q.where("event_time_kind", import_watermelondb10.Q.oneOf(["range", "ongoing"]))
|
|
5255
5307
|
)
|
|
5256
5308
|
).fetch();
|
|
5257
5309
|
const out = [];
|
|
@@ -5306,6 +5358,8 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
5306
5358
|
})
|
|
5307
5359
|
);
|
|
5308
5360
|
const created = await ctx.database.write(async () => {
|
|
5361
|
+
if (ctx.canWrite && !await ctx.canWrite())
|
|
5362
|
+
throw new Error("Memory source is no longer eligible");
|
|
5309
5363
|
const prepared = optionsArray.map(
|
|
5310
5364
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate((record) => {
|
|
5311
5365
|
record._setRaw("content", encryptedContents[i]);
|
|
@@ -5426,12 +5480,12 @@ async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedW
|
|
|
5426
5480
|
async function getAllVaultMemoriesOp(ctx, options) {
|
|
5427
5481
|
const conditions = [
|
|
5428
5482
|
...baseVaultConditions(ctx, options),
|
|
5429
|
-
...options?.scopes?.length ? [
|
|
5483
|
+
...options?.scopes?.length ? [import_watermelondb10.Q.where("scope", import_watermelondb10.Q.oneOf(options.scopes))] : [],
|
|
5430
5484
|
...visibilityConditions(options?.visibility),
|
|
5431
|
-
...options?.folderId !== void 0 ? [
|
|
5432
|
-
...options?.factTypes?.length ? [
|
|
5433
|
-
|
|
5434
|
-
...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [
|
|
5485
|
+
...options?.folderId !== void 0 ? [import_watermelondb10.Q.where("folder_id", options.folderId)] : [],
|
|
5486
|
+
...options?.factTypes?.length ? [import_watermelondb10.Q.where("fact_type", import_watermelondb10.Q.oneOf(options.factTypes))] : [],
|
|
5487
|
+
import_watermelondb10.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb10.Q.desc),
|
|
5488
|
+
...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [import_watermelondb10.Q.take(options.limit)] : []
|
|
5435
5489
|
];
|
|
5436
5490
|
const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
5437
5491
|
return mapInBatches(
|
|
@@ -5454,10 +5508,10 @@ function vaultMemoryRawToRankable(raw) {
|
|
|
5454
5508
|
async function getVaultRankingProjectionsOp(ctx, options) {
|
|
5455
5509
|
const conditions = [
|
|
5456
5510
|
...baseVaultConditions(ctx, options),
|
|
5457
|
-
...options?.scopes?.length ? [
|
|
5458
|
-
...options?.folderId !== void 0 ? [
|
|
5459
|
-
|
|
5460
|
-
...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [
|
|
5511
|
+
...options?.scopes?.length ? [import_watermelondb10.Q.where("scope", import_watermelondb10.Q.oneOf(options.scopes))] : [],
|
|
5512
|
+
...options?.folderId !== void 0 ? [import_watermelondb10.Q.where("folder_id", options.folderId)] : [],
|
|
5513
|
+
import_watermelondb10.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb10.Q.desc),
|
|
5514
|
+
...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [import_watermelondb10.Q.take(options.limit)] : []
|
|
5461
5515
|
];
|
|
5462
5516
|
const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
5463
5517
|
return results.map(vaultMemoryRawToRankable);
|
|
@@ -5492,6 +5546,11 @@ async function getVaultCandidateKeysOp(ctx, options) {
|
|
|
5492
5546
|
});
|
|
5493
5547
|
const clauses = [base.sql];
|
|
5494
5548
|
const args = [...base.args];
|
|
5549
|
+
if (options?.memoryIds !== void 0) {
|
|
5550
|
+
if (options.memoryIds.length === 0) return [];
|
|
5551
|
+
clauses.push(`"id" in (${options.memoryIds.map(() => "?").join(",")})`);
|
|
5552
|
+
args.push(...options.memoryIds);
|
|
5553
|
+
}
|
|
5495
5554
|
if (options?.scopes?.length) {
|
|
5496
5555
|
clauses.push(`"scope" in (${options.scopes.map(() => "?").join(",")})`);
|
|
5497
5556
|
args.push(...options.scopes);
|
|
@@ -5505,7 +5564,7 @@ async function getVaultCandidateKeysOp(ctx, options) {
|
|
|
5505
5564
|
args.push(...options.factTypes);
|
|
5506
5565
|
}
|
|
5507
5566
|
const sql = `select "id", "scope", "folder_id", "embedding_model", "updated_at" from "memory_vault" where ${clauses.join(" and ")}`;
|
|
5508
|
-
const rows = await ctx.vaultMemoryCollection.query(
|
|
5567
|
+
const rows = await ctx.vaultMemoryCollection.query(import_watermelondb10.Q.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
|
|
5509
5568
|
return rows.map(mapRaw);
|
|
5510
5569
|
} catch (err) {
|
|
5511
5570
|
getLogger().debug(
|
|
@@ -5513,11 +5572,12 @@ async function getVaultCandidateKeysOp(ctx, options) {
|
|
|
5513
5572
|
);
|
|
5514
5573
|
const conditions = [
|
|
5515
5574
|
...baseVaultConditions(ctx, {
|
|
5575
|
+
memoryIds: options?.memoryIds,
|
|
5516
5576
|
...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
|
|
5517
5577
|
}),
|
|
5518
|
-
...options?.scopes?.length ? [
|
|
5519
|
-
...options?.folderId !== void 0 ? [
|
|
5520
|
-
...options?.factTypes?.length ? [
|
|
5578
|
+
...options?.scopes?.length ? [import_watermelondb10.Q.where("scope", import_watermelondb10.Q.oneOf(options.scopes))] : [],
|
|
5579
|
+
...options?.folderId !== void 0 ? [import_watermelondb10.Q.where("folder_id", options.folderId)] : [],
|
|
5580
|
+
...options?.factTypes?.length ? [import_watermelondb10.Q.where("fact_type", import_watermelondb10.Q.oneOf(options.factTypes))] : []
|
|
5521
5581
|
];
|
|
5522
5582
|
const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
5523
5583
|
return rows.map(mapRaw);
|
|
@@ -5535,7 +5595,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
|
|
|
5535
5595
|
...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
|
|
5536
5596
|
});
|
|
5537
5597
|
const sql = `select "id", "embedding", "embedding_model" from "memory_vault" where ${base.sql} and "id" in (${ids.map(() => "?").join(",")})`;
|
|
5538
|
-
const rows = await ctx.vaultMemoryCollection.query(
|
|
5598
|
+
const rows = await ctx.vaultMemoryCollection.query(import_watermelondb10.Q.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
|
|
5539
5599
|
return rows.map(mapRaw);
|
|
5540
5600
|
} catch (err) {
|
|
5541
5601
|
getLogger().debug(
|
|
@@ -5547,7 +5607,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
|
|
|
5547
5607
|
includeArchived: options.includeArchived
|
|
5548
5608
|
}
|
|
5549
5609
|
}),
|
|
5550
|
-
|
|
5610
|
+
import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(ids))
|
|
5551
5611
|
).unsafeFetchRaw();
|
|
5552
5612
|
return rows.map(mapRaw);
|
|
5553
5613
|
}
|
|
@@ -5558,7 +5618,7 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
|
|
|
5558
5618
|
...baseVaultConditions(ctx, {
|
|
5559
5619
|
...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
|
|
5560
5620
|
}),
|
|
5561
|
-
|
|
5621
|
+
import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(ids))
|
|
5562
5622
|
];
|
|
5563
5623
|
const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
5564
5624
|
return mapInBatches(
|
|
@@ -5583,7 +5643,7 @@ async function countActiveVaultMemoriesOp(ctx) {
|
|
|
5583
5643
|
}
|
|
5584
5644
|
async function getActiveVaultMemoryIdsOp(ctx, ids) {
|
|
5585
5645
|
if (ids.length === 0) return /* @__PURE__ */ new Set();
|
|
5586
|
-
const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx),
|
|
5646
|
+
const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(ids))).unsafeFetchRaw();
|
|
5587
5647
|
return new Set(rows.map((r) => r.id));
|
|
5588
5648
|
}
|
|
5589
5649
|
async function updateVaultMemoryOp(ctx, id, opts) {
|
|
@@ -5600,10 +5660,23 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
5600
5660
|
const record = probe;
|
|
5601
5661
|
const originalUpdatedAt = record.updatedAt.getTime();
|
|
5602
5662
|
await ctx.database.write(async () => {
|
|
5663
|
+
if (ctx.canWrite && !await ctx.canWrite())
|
|
5664
|
+
throw new Error("Memory source is no longer eligible");
|
|
5603
5665
|
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
|
|
5604
5666
|
stale = true;
|
|
5605
5667
|
return;
|
|
5606
5668
|
}
|
|
5669
|
+
let observedSources = [];
|
|
5670
|
+
let replayedObservation = false;
|
|
5671
|
+
if (opts.observationSourceIds?.length) {
|
|
5672
|
+
try {
|
|
5673
|
+
const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
|
|
5674
|
+
if (Array.isArray(parsed))
|
|
5675
|
+
observedSources = parsed.filter((id2) => typeof id2 === "string");
|
|
5676
|
+
} catch {
|
|
5677
|
+
}
|
|
5678
|
+
replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
|
|
5679
|
+
}
|
|
5607
5680
|
await record.update((r) => {
|
|
5608
5681
|
r._setRaw("content", encryptedContent);
|
|
5609
5682
|
if (opts.scope !== void 0) {
|
|
@@ -5617,9 +5690,15 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
5617
5690
|
r._setRaw("embedding_model", opts.embeddingModel ?? null);
|
|
5618
5691
|
}
|
|
5619
5692
|
if (opts.sourceChunkIds !== void 0) {
|
|
5620
|
-
r._setRaw(
|
|
5693
|
+
r._setRaw(
|
|
5694
|
+
"source_chunk_ids",
|
|
5695
|
+
JSON.stringify(
|
|
5696
|
+
opts.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observedSources, ...opts.sourceChunkIds])] : opts.sourceChunkIds
|
|
5697
|
+
)
|
|
5698
|
+
);
|
|
5621
5699
|
}
|
|
5622
|
-
if (
|
|
5700
|
+
if (replayedObservation) {
|
|
5701
|
+
} else if (opts.proofCountIncrement !== void 0) {
|
|
5623
5702
|
const current = r.proofCount ?? 1;
|
|
5624
5703
|
r._setRaw("proof_count", current + opts.proofCountIncrement);
|
|
5625
5704
|
} else if (opts.proofCount !== void 0) {
|
|
@@ -5636,7 +5715,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
5636
5715
|
if (opts.topicsUserManaged !== void 0) {
|
|
5637
5716
|
r._setRaw("topics_user_managed", opts.topicsUserManaged);
|
|
5638
5717
|
}
|
|
5639
|
-
if (opts.lastObservedAt !== void 0) {
|
|
5718
|
+
if (opts.lastObservedAt !== void 0 && !replayedObservation) {
|
|
5640
5719
|
r._setRaw("last_observed_at", opts.lastObservedAt);
|
|
5641
5720
|
}
|
|
5642
5721
|
if (opts.factType !== void 0) {
|
|
@@ -5762,6 +5841,8 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
5762
5841
|
}
|
|
5763
5842
|
let stale = false;
|
|
5764
5843
|
await ctx.database.write(async () => {
|
|
5844
|
+
if (ctx.canWrite && !await ctx.canWrite())
|
|
5845
|
+
throw new Error("Memory source is no longer eligible");
|
|
5765
5846
|
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
|
|
5766
5847
|
stale = true;
|
|
5767
5848
|
return;
|
|
@@ -5782,9 +5863,9 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
5782
5863
|
}
|
|
5783
5864
|
async function getUnfiledVaultMemoriesOp(ctx) {
|
|
5784
5865
|
const conditions = [
|
|
5785
|
-
|
|
5866
|
+
import_watermelondb10.Q.where("folder_id", null),
|
|
5786
5867
|
...baseVaultConditions(ctx),
|
|
5787
|
-
|
|
5868
|
+
import_watermelondb10.Q.sortBy("created_at", import_watermelondb10.Q.desc)
|
|
5788
5869
|
];
|
|
5789
5870
|
const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
|
|
5790
5871
|
return mapInBatches(
|
|
@@ -5797,7 +5878,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
|
|
|
5797
5878
|
const entityIdByMemory = /* @__PURE__ */ new Map();
|
|
5798
5879
|
const allEntityIds = /* @__PURE__ */ new Set();
|
|
5799
5880
|
for (let i = 0; i < memoryIds.length; i += CHUNK) {
|
|
5800
|
-
const links = await entityCtx.memoryEntityCollection.query(
|
|
5881
|
+
const links = await entityCtx.memoryEntityCollection.query(import_watermelondb10.Q.where("memory_id", import_watermelondb10.Q.oneOf(memoryIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
|
|
5801
5882
|
for (const link of links) {
|
|
5802
5883
|
const memoryId = String(link.memory_id);
|
|
5803
5884
|
const entityId = String(link.entity_id);
|
|
@@ -5813,7 +5894,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
|
|
|
5813
5894
|
const entityIds = Array.from(allEntityIds);
|
|
5814
5895
|
const nameById = /* @__PURE__ */ new Map();
|
|
5815
5896
|
for (let i = 0; i < entityIds.length; i += CHUNK) {
|
|
5816
|
-
const entities = await entityCtx.entityCollection.query(
|
|
5897
|
+
const entities = await entityCtx.entityCollection.query(import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(entityIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
|
|
5817
5898
|
for (const e of entities) {
|
|
5818
5899
|
if (typeof e.canonical_name === "string") nameById.set(String(e.id), e.canonical_name);
|
|
5819
5900
|
}
|
|
@@ -5842,7 +5923,7 @@ async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
|
|
|
5842
5923
|
if (!entityCtx) {
|
|
5843
5924
|
throw new Error("getMemoriesNeedingTopicExtractionOp requires ctx.entityCtx");
|
|
5844
5925
|
}
|
|
5845
|
-
const conditions = [...baseVaultConditions(ctx),
|
|
5926
|
+
const conditions = [...baseVaultConditions(ctx), import_watermelondb10.Q.sortBy("created_at", import_watermelondb10.Q.desc)];
|
|
5846
5927
|
const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
5847
5928
|
const linkedNames = await linkedEntityNamesByMemory(
|
|
5848
5929
|
entityCtx,
|
|
@@ -5993,10 +6074,10 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
5993
6074
|
}
|
|
5994
6075
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
|
|
5995
6076
|
if (parseTopics(record.topics) !== null) continue;
|
|
5996
|
-
const links = await entityCtx.memoryEntityCollection.query(
|
|
6077
|
+
const links = await entityCtx.memoryEntityCollection.query(import_watermelondb10.Q.where("memory_id", id)).unsafeFetchRaw();
|
|
5997
6078
|
const entityIds = links.map((l) => String(l.entity_id));
|
|
5998
6079
|
if (entityIds.length === 0) continue;
|
|
5999
|
-
const entities = await entityCtx.entityCollection.query(
|
|
6080
|
+
const entities = await entityCtx.entityCollection.query(import_watermelondb10.Q.where("id", import_watermelondb10.Q.oneOf(entityIds))).fetch();
|
|
6000
6081
|
if (entities.length === 0) continue;
|
|
6001
6082
|
const source = record.topicsUserManaged ? "user" : "auto";
|
|
6002
6083
|
const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
|
|
@@ -6012,7 +6093,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
6012
6093
|
}
|
|
6013
6094
|
async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
6014
6095
|
if (ctx.userId !== void 0 && ctx.userId !== userId) return 0;
|
|
6015
|
-
const records = await ctx.vaultMemoryCollection.query(
|
|
6096
|
+
const records = await ctx.vaultMemoryCollection.query(import_watermelondb10.Q.where("user_id", userId), import_watermelondb10.Q.where("is_deleted", false)).fetch();
|
|
6016
6097
|
if (records.length === 0) return 0;
|
|
6017
6098
|
await ctx.database.write(async () => {
|
|
6018
6099
|
const prepared = records.map(
|
|
@@ -6053,6 +6134,7 @@ async function getDecayCandidatesRawOp(ctx) {
|
|
|
6053
6134
|
eventTimeEnd: raw.event_time_end ?? null,
|
|
6054
6135
|
eventTimeKind: raw.event_time_kind ?? null,
|
|
6055
6136
|
updatedAt: raw.updated_at,
|
|
6137
|
+
lastObservedAt: raw.last_observed_at ?? null,
|
|
6056
6138
|
archivedAt: raw.archived_at ?? null,
|
|
6057
6139
|
source: raw.source ?? null,
|
|
6058
6140
|
trustTier: raw.trust_tier ?? null
|
|
@@ -6069,7 +6151,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
6069
6151
|
stale = true;
|
|
6070
6152
|
return;
|
|
6071
6153
|
}
|
|
6072
|
-
if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt) {
|
|
6154
|
+
if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
|
|
6073
6155
|
stale = true;
|
|
6074
6156
|
return;
|
|
6075
6157
|
}
|
|
@@ -6144,11 +6226,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel)
|
|
|
6144
6226
|
return false;
|
|
6145
6227
|
}
|
|
6146
6228
|
}
|
|
6147
|
-
var
|
|
6229
|
+
var import_watermelondb10, NON_PRIVATE_VISIBILITIES, KNOWN_TRUST_TIERS, TOPICS_EXTRACTION_VERSION;
|
|
6148
6230
|
var init_operations3 = __esm({
|
|
6149
6231
|
"src/lib/db/memoryVault/operations.ts"() {
|
|
6150
6232
|
"use strict";
|
|
6151
|
-
|
|
6233
|
+
import_watermelondb10 = require("@nozbe/watermelondb");
|
|
6152
6234
|
init_logger();
|
|
6153
6235
|
init_operations2();
|
|
6154
6236
|
init_types3();
|
|
@@ -7654,7 +7736,9 @@ function dedupeBy(items, ...keys) {
|
|
|
7654
7736
|
return out;
|
|
7655
7737
|
}
|
|
7656
7738
|
async function recall(query, ctx, options = {}) {
|
|
7657
|
-
const
|
|
7739
|
+
const requestedTypes = options.types ?? ["fact"];
|
|
7740
|
+
const chunksScopeRestricted = options.memoryIds !== void 0 && requestedTypes.includes("chunk");
|
|
7741
|
+
const types = options.memoryIds !== void 0 ? requestedTypes.filter((kind) => kind === "fact") : requestedTypes;
|
|
7658
7742
|
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
7659
7743
|
const usedBudget = options.budget ?? DEFAULT_BUDGET;
|
|
7660
7744
|
const flags = flagsForBudget(usedBudget);
|
|
@@ -7706,7 +7790,10 @@ async function recall(query, ctx, options = {}) {
|
|
|
7706
7790
|
if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
|
|
7707
7791
|
if (graphLaneFailed) degraded.push("graph-lane-failed");
|
|
7708
7792
|
if (temporalLaneFailed) degraded.push("temporal-lane-failed");
|
|
7709
|
-
|
|
7793
|
+
if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
|
|
7794
|
+
const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || // The chunk lane was wired and deliberately dropped for the scope, which
|
|
7795
|
+
// is not the "requested kinds have no store" wiring bug `no-lanes` means.
|
|
7796
|
+
chunksScopeRestricted && !!ctx.storageCtx;
|
|
7710
7797
|
const scores = admitted.map((m) => m.score);
|
|
7711
7798
|
const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
|
|
7712
7799
|
const diagnostics = {
|
|
@@ -7851,6 +7938,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
7851
7938
|
...options.scopes && { scopes: options.scopes },
|
|
7852
7939
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
7853
7940
|
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
7941
|
+
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
7854
7942
|
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
7855
7943
|
...entityRanking.length > 0 && { entityRanking },
|
|
7856
7944
|
...temporalRanking.length > 0 && { temporalRanking }
|
|
@@ -8854,6 +8942,7 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
8854
8942
|
const scopes = searchOptions?.scopes;
|
|
8855
8943
|
const folderId = searchOptions?.folderId;
|
|
8856
8944
|
const queryOpts = {};
|
|
8945
|
+
if (searchOptions?.memoryIds !== void 0) queryOpts.memoryIds = searchOptions.memoryIds;
|
|
8857
8946
|
if (scopes?.length) queryOpts.scopes = scopes;
|
|
8858
8947
|
if (folderId !== void 0) queryOpts.folderId = folderId;
|
|
8859
8948
|
if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
|
|
@@ -9715,6 +9804,7 @@ __export(index_exports, {
|
|
|
9715
9804
|
WalletPoller: () => WalletPoller,
|
|
9716
9805
|
addConversationMemoriesOp: () => addConversationMemoriesOp,
|
|
9717
9806
|
archiveVaultMemoryOp: () => archiveVaultMemoryOp,
|
|
9807
|
+
assembleMemoryContext: () => assembleMemoryContext,
|
|
9718
9808
|
backfillMemoryTopicsOp: () => backfillMemoryTopicsOp,
|
|
9719
9809
|
buildNotionAuthUrl: () => buildNotionAuthUrl,
|
|
9720
9810
|
capHopsForDensity: () => capHopsForDensity,
|
|
@@ -9747,6 +9837,7 @@ __export(index_exports, {
|
|
|
9747
9837
|
createChunkVectorCache: () => createChunkVectorCache,
|
|
9748
9838
|
createCryptoPricePreProcessor: () => createCryptoPricePreProcessor,
|
|
9749
9839
|
createDecaySweeper: () => createDecaySweeper,
|
|
9840
|
+
createDurableAutoExtractor: () => createDurableAutoExtractor,
|
|
9750
9841
|
createLlmDecayClassifier: () => createLlmDecayClassifier,
|
|
9751
9842
|
createLlmNeighborRefiner: () => createLlmNeighborRefiner,
|
|
9752
9843
|
createMemoryEngineTool: () => createMemoryEngineTool,
|
|
@@ -9767,6 +9858,7 @@ __export(index_exports, {
|
|
|
9767
9858
|
decodeChunkVector: () => decodeChunkVector,
|
|
9768
9859
|
decryptConversationTitle: () => decryptConversationTitle,
|
|
9769
9860
|
deleteAllVaultMemoriesForUserOp: () => deleteAllVaultMemoriesForUserOp,
|
|
9861
|
+
deleteMessageOp: () => deleteMessageOp,
|
|
9770
9862
|
deleteVaultFolderOp: () => deleteVaultFolderOp,
|
|
9771
9863
|
deleteVaultMemoryOp: () => deleteVaultMemoryOp,
|
|
9772
9864
|
dequantizeEmbedding: () => dequantizeEmbedding,
|
|
@@ -9839,6 +9931,7 @@ __export(index_exports, {
|
|
|
9839
9931
|
setLogger: () => setLogger,
|
|
9840
9932
|
setMemoryVisibilityOp: () => setMemoryVisibilityOp,
|
|
9841
9933
|
shouldChunkMessage: () => shouldChunkMessage,
|
|
9934
|
+
shouldRecallMemory: () => shouldRecallMemory,
|
|
9842
9935
|
stampTopicsExtractedAtOp: () => stampTopicsExtractedAtOp,
|
|
9843
9936
|
streamCancelPath: () => streamCancelPath,
|
|
9844
9937
|
streamReplayPath: () => streamReplayPath,
|
|
@@ -14313,7 +14406,7 @@ function extractSourcesFromToolCallEvents(toolCallEvents) {
|
|
|
14313
14406
|
init_clientConfig();
|
|
14314
14407
|
|
|
14315
14408
|
// src/lib/db/chat/summaryOperations.ts
|
|
14316
|
-
var
|
|
14409
|
+
var import_watermelondb3 = require("@nozbe/watermelondb");
|
|
14317
14410
|
function createSummaryContext(database) {
|
|
14318
14411
|
return {
|
|
14319
14412
|
database,
|
|
@@ -14332,14 +14425,14 @@ function modelToStored(record) {
|
|
|
14332
14425
|
};
|
|
14333
14426
|
}
|
|
14334
14427
|
async function getConversationSummaryOp(ctx, conversationId) {
|
|
14335
|
-
const results = await ctx.summariesCollection.query(
|
|
14428
|
+
const results = await ctx.summariesCollection.query(import_watermelondb3.Q.where("conversation_id", conversationId)).fetch();
|
|
14336
14429
|
if (results.length === 0) return null;
|
|
14337
14430
|
return modelToStored(results[0]);
|
|
14338
14431
|
}
|
|
14339
14432
|
async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
|
|
14340
14433
|
let record;
|
|
14341
14434
|
await ctx.database.write(async () => {
|
|
14342
|
-
const existing = await ctx.summariesCollection.query(
|
|
14435
|
+
const existing = await ctx.summariesCollection.query(import_watermelondb3.Q.where("conversation_id", conversationId)).fetch();
|
|
14343
14436
|
if (existing.length > 0) {
|
|
14344
14437
|
record = await existing[0].update((rec) => {
|
|
14345
14438
|
rec.summary = summary;
|
|
@@ -14359,7 +14452,7 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
|
|
|
14359
14452
|
}
|
|
14360
14453
|
async function deleteConversationSummaryOp(ctx, conversationId) {
|
|
14361
14454
|
await ctx.database.write(async () => {
|
|
14362
|
-
const existing = await ctx.summariesCollection.query(
|
|
14455
|
+
const existing = await ctx.summariesCollection.query(import_watermelondb3.Q.where("conversation_id", conversationId)).fetch();
|
|
14363
14456
|
for (const record of existing) {
|
|
14364
14457
|
await record.destroyPermanently();
|
|
14365
14458
|
}
|
|
@@ -14851,9 +14944,9 @@ async function decryptConversationTitle(encryptedTitle, address) {
|
|
|
14851
14944
|
}
|
|
14852
14945
|
|
|
14853
14946
|
// src/lib/db/chat/models.ts
|
|
14854
|
-
var
|
|
14947
|
+
var import_watermelondb4 = require("@nozbe/watermelondb");
|
|
14855
14948
|
var import_decorators = require("@nozbe/watermelondb/decorators");
|
|
14856
|
-
var Message = class extends
|
|
14949
|
+
var Message = class extends import_watermelondb4.Model {
|
|
14857
14950
|
};
|
|
14858
14951
|
Message.table = "history";
|
|
14859
14952
|
Message.associations = {
|
|
@@ -14932,7 +15025,7 @@ __decorateClass([
|
|
|
14932
15025
|
__decorateClass([
|
|
14933
15026
|
(0, import_decorators.text)("origin")
|
|
14934
15027
|
], Message.prototype, "origin", 2);
|
|
14935
|
-
var Conversation = class extends
|
|
15028
|
+
var Conversation = class extends import_watermelondb4.Model {
|
|
14936
15029
|
};
|
|
14937
15030
|
Conversation.table = "conversations";
|
|
14938
15031
|
Conversation.associations = {
|
|
@@ -14960,7 +15053,7 @@ __decorateClass([
|
|
|
14960
15053
|
__decorateClass([
|
|
14961
15054
|
(0, import_decorators.date)("pinned_at")
|
|
14962
15055
|
], Conversation.prototype, "pinnedAt", 2);
|
|
14963
|
-
var ConversationSummary = class extends
|
|
15056
|
+
var ConversationSummary = class extends import_watermelondb4.Model {
|
|
14964
15057
|
};
|
|
14965
15058
|
ConversationSummary.table = "conversation_summaries";
|
|
14966
15059
|
ConversationSummary.associations = {
|
|
@@ -14989,12 +15082,12 @@ __decorateClass([
|
|
|
14989
15082
|
init_operations();
|
|
14990
15083
|
|
|
14991
15084
|
// src/lib/db/chat/schema.ts
|
|
14992
|
-
var
|
|
15085
|
+
var import_watermelondb5 = require("@nozbe/watermelondb");
|
|
14993
15086
|
var import_migrations = require("@nozbe/watermelondb/Schema/migrations");
|
|
14994
|
-
var chatStorageSchema = (0,
|
|
15087
|
+
var chatStorageSchema = (0, import_watermelondb5.appSchema)({
|
|
14995
15088
|
version: 7,
|
|
14996
15089
|
tables: [
|
|
14997
|
-
(0,
|
|
15090
|
+
(0, import_watermelondb5.tableSchema)({
|
|
14998
15091
|
name: "history",
|
|
14999
15092
|
columns: [
|
|
15000
15093
|
{ name: "message_id", type: "number" },
|
|
@@ -15021,7 +15114,7 @@ var chatStorageSchema = (0, import_watermelondb4.appSchema)({
|
|
|
15021
15114
|
// Reasoning/thinking content
|
|
15022
15115
|
]
|
|
15023
15116
|
}),
|
|
15024
|
-
(0,
|
|
15117
|
+
(0, import_watermelondb5.tableSchema)({
|
|
15025
15118
|
name: "conversations",
|
|
15026
15119
|
columns: [
|
|
15027
15120
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
@@ -15096,9 +15189,9 @@ var chatStorageMigrations = (0, import_migrations.schemaMigrations)({
|
|
|
15096
15189
|
init_types2();
|
|
15097
15190
|
|
|
15098
15191
|
// src/lib/db/media/models.ts
|
|
15099
|
-
var
|
|
15192
|
+
var import_watermelondb6 = require("@nozbe/watermelondb");
|
|
15100
15193
|
var import_decorators2 = require("@nozbe/watermelondb/decorators");
|
|
15101
|
-
var Media = class extends
|
|
15194
|
+
var Media = class extends import_watermelondb6.Model {
|
|
15102
15195
|
};
|
|
15103
15196
|
Media.table = "media";
|
|
15104
15197
|
Media.associations = {
|
|
@@ -15165,7 +15258,7 @@ function generateMediaId() {
|
|
|
15165
15258
|
}
|
|
15166
15259
|
|
|
15167
15260
|
// src/lib/db/media/operations.ts
|
|
15168
|
-
var
|
|
15261
|
+
var import_watermelondb7 = require("@nozbe/watermelondb");
|
|
15169
15262
|
|
|
15170
15263
|
// src/lib/storage/mcpImages.ts
|
|
15171
15264
|
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -15367,7 +15460,7 @@ async function createMediaBatchOp(ctx, optionsArray) {
|
|
|
15367
15460
|
})
|
|
15368
15461
|
);
|
|
15369
15462
|
});
|
|
15370
|
-
const results = await mediaCollection.query(
|
|
15463
|
+
const results = await mediaCollection.query(import_watermelondb7.Q.where("media_id", import_watermelondb7.Q.oneOf(mediaIds))).fetch();
|
|
15371
15464
|
return Promise.all(
|
|
15372
15465
|
results.map(
|
|
15373
15466
|
(m) => mediaToStored(m, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -15377,7 +15470,7 @@ async function createMediaBatchOp(ctx, optionsArray) {
|
|
|
15377
15470
|
var IMAGE_VIDEO_MIMES = VIDEO_EXTENSIONS.map((ext) => `image/${ext}`);
|
|
15378
15471
|
async function deleteMediaByConversationOp(ctx, conversationId) {
|
|
15379
15472
|
const mediaCollection = ctx.database.get("media");
|
|
15380
|
-
const results = await mediaCollection.query(
|
|
15473
|
+
const results = await mediaCollection.query(import_watermelondb7.Q.where("conversation_id", conversationId), import_watermelondb7.Q.where("is_deleted", false)).fetch();
|
|
15381
15474
|
if (results.length === 0) {
|
|
15382
15475
|
return 0;
|
|
15383
15476
|
}
|
|
@@ -15398,9 +15491,9 @@ async function deleteMediaByConversationOp(ctx, conversationId) {
|
|
|
15398
15491
|
}
|
|
15399
15492
|
|
|
15400
15493
|
// src/lib/db/memoryVault/models.ts
|
|
15401
|
-
var
|
|
15494
|
+
var import_watermelondb8 = require("@nozbe/watermelondb");
|
|
15402
15495
|
var import_decorators3 = require("@nozbe/watermelondb/decorators");
|
|
15403
|
-
var VaultMemory = class extends
|
|
15496
|
+
var VaultMemory = class extends import_watermelondb8.Model {
|
|
15404
15497
|
};
|
|
15405
15498
|
VaultMemory.table = "memory_vault";
|
|
15406
15499
|
__decorateClass([
|
|
@@ -15563,7 +15656,8 @@ function classifyDecay(m, now, policy) {
|
|
|
15563
15656
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
15564
15657
|
if (m.eventTimeEnd >= now) return "keep";
|
|
15565
15658
|
}
|
|
15566
|
-
|
|
15659
|
+
const observedAt = Number.isFinite(m.lastObservedAt) ? m.lastObservedAt : m.updatedAt;
|
|
15660
|
+
if (now - Math.max(m.updatedAt, observedAt) > ttlForType(m.factType, resolved)) return "archive";
|
|
15567
15661
|
return "keep";
|
|
15568
15662
|
}
|
|
15569
15663
|
|
|
@@ -15977,7 +16071,7 @@ var WalletPoller = class {
|
|
|
15977
16071
|
init_logger();
|
|
15978
16072
|
|
|
15979
16073
|
// src/lib/memory/autoExtract.ts
|
|
15980
|
-
var
|
|
16074
|
+
var import_watermelondb11 = require("@nozbe/watermelondb");
|
|
15981
16075
|
init_operations2();
|
|
15982
16076
|
init_types3();
|
|
15983
16077
|
init_logger();
|
|
@@ -16493,6 +16587,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
16493
16587
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
|
|
16494
16588
|
content: existing.content,
|
|
16495
16589
|
proofCountIncrement: 1,
|
|
16590
|
+
observationSourceIds: options.sourceChunkIds,
|
|
16496
16591
|
sourceChunkIds: mergedSourceIds,
|
|
16497
16592
|
// resurrect encodes the decay gate: ACTIVE target → { preserveUpdatedAt:
|
|
16498
16593
|
// true } (main's normal re-observation path — bump proof_count without
|
|
@@ -16736,6 +16831,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16736
16831
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
|
|
16737
16832
|
content: existing.content,
|
|
16738
16833
|
proofCountIncrement: 1,
|
|
16834
|
+
observationSourceIds: options.sourceChunkIds,
|
|
16739
16835
|
sourceChunkIds: mergedSourceIds,
|
|
16740
16836
|
// ACTIVE target → { preserveUpdatedAt: true } (main's normal re-observation
|
|
16741
16837
|
// path); ARCHIVED (non-superseded, non-deleted) → { restore: true } and no
|
|
@@ -16785,6 +16881,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
16785
16881
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
|
|
16786
16882
|
content: decision.content,
|
|
16787
16883
|
proofCountIncrement: 1,
|
|
16884
|
+
observationSourceIds: options.sourceChunkIds,
|
|
16788
16885
|
sourceChunkIds: mergedSourceIds,
|
|
16789
16886
|
embedding: JSON.stringify(newEmbedding),
|
|
16790
16887
|
embeddingModel: consolidatedModel,
|
|
@@ -16836,7 +16933,7 @@ async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
|
16836
16933
|
// src/lib/memory/autoExtract.ts
|
|
16837
16934
|
async function isMemoryTopicsUserManaged(ctx, memoryId) {
|
|
16838
16935
|
try {
|
|
16839
|
-
const rows = await ctx.database.get(VaultMemory.table).query(
|
|
16936
|
+
const rows = await ctx.database.get(VaultMemory.table).query(import_watermelondb11.Q.where("id", memoryId)).fetch();
|
|
16840
16937
|
return rows[0]?.topicsUserManaged === true;
|
|
16841
16938
|
} catch {
|
|
16842
16939
|
return true;
|
|
@@ -17423,7 +17520,7 @@ function createAutoExtractor(options) {
|
|
|
17423
17520
|
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
17424
17521
|
}
|
|
17425
17522
|
});
|
|
17426
|
-
if (outcome !== "empty-after-retry") {
|
|
17523
|
+
if (outcome !== "empty-after-retry" && failedCount === 0) {
|
|
17427
17524
|
const advancedTo = window2[window2.length - 1].id;
|
|
17428
17525
|
stateFor(conversationId).watermark = advancedTo;
|
|
17429
17526
|
persistCursor(conversationId, messages, advancedTo, contiguous);
|
|
@@ -17584,6 +17681,7 @@ function toDecayInput(c) {
|
|
|
17584
17681
|
eventTimeEnd: c.eventTimeEnd,
|
|
17585
17682
|
eventTimeKind: c.eventTimeKind,
|
|
17586
17683
|
updatedAt: c.updatedAt,
|
|
17684
|
+
lastObservedAt: c.lastObservedAt,
|
|
17587
17685
|
archivedAt: c.archivedAt,
|
|
17588
17686
|
source: c.source,
|
|
17589
17687
|
trustTier: c.trustTier
|
|
@@ -17665,7 +17763,8 @@ function createDecaySweeper(options) {
|
|
|
17665
17763
|
for (const c of toArchive) {
|
|
17666
17764
|
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
17667
17765
|
now,
|
|
17668
|
-
expectedUpdatedAt: c.updatedAt
|
|
17766
|
+
expectedUpdatedAt: c.updatedAt,
|
|
17767
|
+
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
17669
17768
|
});
|
|
17670
17769
|
if (ok) archived++;
|
|
17671
17770
|
}
|
|
@@ -17921,6 +18020,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
17921
18020
|
budget: defaultBudget,
|
|
17922
18021
|
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
17923
18022
|
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
18023
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
17924
18024
|
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
17925
18025
|
...toolOptions?.excludeConversationId && {
|
|
17926
18026
|
excludeConversationId: toolOptions.excludeConversationId
|
|
@@ -19136,6 +19236,465 @@ function createMessageSourceResolver(ctx) {
|
|
|
19136
19236
|
};
|
|
19137
19237
|
}
|
|
19138
19238
|
|
|
19239
|
+
// src/lib/memory/context.ts
|
|
19240
|
+
function shouldRecallMemory(query) {
|
|
19241
|
+
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
19242
|
+
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
19243
|
+
normalized
|
|
19244
|
+
);
|
|
19245
|
+
}
|
|
19246
|
+
async function assembleMemoryContext(options) {
|
|
19247
|
+
const { query, recall: recall2, loadFacts, loadSessionRefs } = options;
|
|
19248
|
+
const memoryIds = options.memoryIds ?? options.recallOptions?.memoryIds;
|
|
19249
|
+
const ranked = shouldRecallMemory(query);
|
|
19250
|
+
const degraded = [];
|
|
19251
|
+
const guard = async (lane, run, fallback) => {
|
|
19252
|
+
try {
|
|
19253
|
+
return await run();
|
|
19254
|
+
} catch (error) {
|
|
19255
|
+
degraded.push(lane);
|
|
19256
|
+
try {
|
|
19257
|
+
options.onDegraded?.(lane, error);
|
|
19258
|
+
} catch {
|
|
19259
|
+
}
|
|
19260
|
+
return fallback;
|
|
19261
|
+
}
|
|
19262
|
+
};
|
|
19263
|
+
const scoped = memoryIds !== void 0 || options.recallOptions?.scopes !== void 0 || options.recallOptions?.folderId !== void 0;
|
|
19264
|
+
const allowed = memoryIds !== void 0 ? new Set(memoryIds) : void 0;
|
|
19265
|
+
const filters = {
|
|
19266
|
+
...options.recallOptions?.scopes && { scopes: options.recallOptions.scopes },
|
|
19267
|
+
...options.recallOptions?.folderId !== void 0 && {
|
|
19268
|
+
folderId: options.recallOptions.folderId
|
|
19269
|
+
}
|
|
19270
|
+
};
|
|
19271
|
+
const active = (m) => !m.isDeleted && !m.archivedAt && !m.supersededBy && m.trustTier !== "quarantined" && (!allowed || allowed.has(m.uniqueId));
|
|
19272
|
+
const asItem = (m, lane, score = 1) => ({
|
|
19273
|
+
id: m.uniqueId,
|
|
19274
|
+
content: m.content,
|
|
19275
|
+
score,
|
|
19276
|
+
lane,
|
|
19277
|
+
sourceIds: m.sourceChunkIds ?? []
|
|
19278
|
+
});
|
|
19279
|
+
const empty = {
|
|
19280
|
+
memories: [],
|
|
19281
|
+
usedBudget: options.recallOptions?.budget ?? "low",
|
|
19282
|
+
reranked: false,
|
|
19283
|
+
candidateCount: 0
|
|
19284
|
+
};
|
|
19285
|
+
const [facts, episodes, profile, session] = await Promise.all([
|
|
19286
|
+
ranked ? guard(
|
|
19287
|
+
"fact",
|
|
19288
|
+
() => recall2(query, { ...options.recallOptions, types: ["fact"], limit: 20, memoryIds }),
|
|
19289
|
+
empty
|
|
19290
|
+
) : empty,
|
|
19291
|
+
ranked && !scoped && options.includeEpisodes !== false ? guard(
|
|
19292
|
+
"episode",
|
|
19293
|
+
() => recall2(query, {
|
|
19294
|
+
...options.recallOptions,
|
|
19295
|
+
types: ["chunk"],
|
|
19296
|
+
limit: 4,
|
|
19297
|
+
minScore: 0.5,
|
|
19298
|
+
onDiagnostics: void 0
|
|
19299
|
+
}),
|
|
19300
|
+
empty
|
|
19301
|
+
) : empty,
|
|
19302
|
+
loadFacts ? guard(
|
|
19303
|
+
"profile",
|
|
19304
|
+
async () => {
|
|
19305
|
+
const stable = await loadFacts({
|
|
19306
|
+
...filters,
|
|
19307
|
+
memoryIds,
|
|
19308
|
+
factTypes: ["identity", "preference", "constraint", "relationship"],
|
|
19309
|
+
limit: 8
|
|
19310
|
+
});
|
|
19311
|
+
const dynamic = await loadFacts({
|
|
19312
|
+
...filters,
|
|
19313
|
+
memoryIds,
|
|
19314
|
+
factTypes: ["ongoing_context", "plan"],
|
|
19315
|
+
limit: 4
|
|
19316
|
+
});
|
|
19317
|
+
return [...stable, ...dynamic].filter(active).map((m) => asItem(m, "profile"));
|
|
19318
|
+
},
|
|
19319
|
+
[]
|
|
19320
|
+
) : [],
|
|
19321
|
+
loadFacts && loadSessionRefs ? guard(
|
|
19322
|
+
"session",
|
|
19323
|
+
async () => {
|
|
19324
|
+
const refs = (await loadSessionRefs()).filter((r) => !allowed || allowed.has(r.memoryId)).sort((a, b) => b.score - a.score).slice(0, 10);
|
|
19325
|
+
if (!refs.length) return [];
|
|
19326
|
+
const rows = await loadFacts({ ...filters, memoryIds: refs.map((r) => r.memoryId) });
|
|
19327
|
+
const byId = new Map(rows.filter(active).map((m) => [m.uniqueId, m]));
|
|
19328
|
+
return refs.flatMap((ref) => {
|
|
19329
|
+
const m = byId.get(ref.memoryId);
|
|
19330
|
+
return m ? [asItem(m, "session", ref.score)] : [];
|
|
19331
|
+
});
|
|
19332
|
+
},
|
|
19333
|
+
[]
|
|
19334
|
+
) : []
|
|
19335
|
+
]);
|
|
19336
|
+
const toItems = (result, lane) => result.memories.filter((m) => !allowed || allowed.has(m.id)).map((m) => ({
|
|
19337
|
+
id: m.id,
|
|
19338
|
+
content: m.content,
|
|
19339
|
+
score: m.score,
|
|
19340
|
+
lane,
|
|
19341
|
+
...lane === "fact" && { recalled: true },
|
|
19342
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
19343
|
+
}));
|
|
19344
|
+
const recalledFacts = toItems(facts, "fact");
|
|
19345
|
+
const recalledScores = /* @__PURE__ */ new Map();
|
|
19346
|
+
const recalledContentScores = /* @__PURE__ */ new Map();
|
|
19347
|
+
for (const item of recalledFacts) {
|
|
19348
|
+
recalledScores.set(item.id, Math.max(recalledScores.get(item.id) ?? -Infinity, item.score));
|
|
19349
|
+
const content = item.content.trim();
|
|
19350
|
+
recalledContentScores.set(
|
|
19351
|
+
content,
|
|
19352
|
+
Math.max(recalledContentScores.get(content) ?? -Infinity, item.score)
|
|
19353
|
+
);
|
|
19354
|
+
}
|
|
19355
|
+
const rankedProfile = profile.map((item) => {
|
|
19356
|
+
const score = Math.max(
|
|
19357
|
+
recalledScores.get(item.id) ?? -Infinity,
|
|
19358
|
+
recalledContentScores.get(item.content.trim()) ?? -Infinity
|
|
19359
|
+
);
|
|
19360
|
+
return score === -Infinity ? item : { ...item, score, recalled: true };
|
|
19361
|
+
});
|
|
19362
|
+
const lanes = [
|
|
19363
|
+
[rankedProfile, 2e3],
|
|
19364
|
+
[recalledFacts, 6e3],
|
|
19365
|
+
[toItems(episodes, "episode"), 3e3],
|
|
19366
|
+
[session, 1e3]
|
|
19367
|
+
];
|
|
19368
|
+
const items = [];
|
|
19369
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
19370
|
+
const seenContent = /* @__PURE__ */ new Set();
|
|
19371
|
+
let remaining = Math.max(0, options.maxChars ?? 12e3);
|
|
19372
|
+
let truncated = false;
|
|
19373
|
+
for (const [candidates, laneBudget] of lanes) {
|
|
19374
|
+
let laneRemaining = Math.min(laneBudget, remaining);
|
|
19375
|
+
for (const item of candidates) {
|
|
19376
|
+
const content = item.content?.trim();
|
|
19377
|
+
const key = `${item.lane === "episode" ? "episode" : "fact"}:${item.id}`;
|
|
19378
|
+
if (!content || seenIds.has(key) || seenContent.has(content)) continue;
|
|
19379
|
+
if (content.length > laneRemaining) {
|
|
19380
|
+
truncated = true;
|
|
19381
|
+
continue;
|
|
19382
|
+
}
|
|
19383
|
+
items.push({ ...item, content });
|
|
19384
|
+
seenIds.add(key);
|
|
19385
|
+
seenContent.add(content);
|
|
19386
|
+
remaining -= content.length;
|
|
19387
|
+
laneRemaining -= content.length;
|
|
19388
|
+
}
|
|
19389
|
+
}
|
|
19390
|
+
return { items, ranked, rankedCount: recalledFacts.length, degraded, truncated };
|
|
19391
|
+
}
|
|
19392
|
+
|
|
19393
|
+
// src/lib/memory/durableExtraction.ts
|
|
19394
|
+
var import_watermelondb12 = require("@nozbe/watermelondb");
|
|
19395
|
+
init_encryption();
|
|
19396
|
+
init_operations();
|
|
19397
|
+
init_models();
|
|
19398
|
+
var MAX_JOBS_PER_PASS = 3;
|
|
19399
|
+
var MAX_ATTEMPTS = 3;
|
|
19400
|
+
function idsOf(job) {
|
|
19401
|
+
return JSON.parse(String(job._getRaw("message_ids")));
|
|
19402
|
+
}
|
|
19403
|
+
function seqOf(job) {
|
|
19404
|
+
const raw = job._getRaw("watermark_seq");
|
|
19405
|
+
return typeof raw === "number" && raw > 0 ? raw : void 0;
|
|
19406
|
+
}
|
|
19407
|
+
function createDurableAutoExtractor(options) {
|
|
19408
|
+
const vault = options.retainCtx.vaultCtx;
|
|
19409
|
+
const database = vault.database;
|
|
19410
|
+
const owner = vault.userId ?? vault.walletAddress;
|
|
19411
|
+
if (!owner) throw new Error("Durable extraction requires a user or wallet owner");
|
|
19412
|
+
const jobs = database.get(ExtractionJob.table);
|
|
19413
|
+
const storage = {
|
|
19414
|
+
database,
|
|
19415
|
+
messagesCollection: database.get("history"),
|
|
19416
|
+
conversationsCollection: database.get("conversations"),
|
|
19417
|
+
walletAddress: vault.walletAddress,
|
|
19418
|
+
signMessage: vault.signMessage,
|
|
19419
|
+
embeddedWalletSigner: vault.embeddedWalletSigner
|
|
19420
|
+
};
|
|
19421
|
+
const folderId = options.folderId ?? null;
|
|
19422
|
+
let disposed = false;
|
|
19423
|
+
let running = false;
|
|
19424
|
+
let wakeRequested = false;
|
|
19425
|
+
let timer;
|
|
19426
|
+
let writes = Promise.resolve();
|
|
19427
|
+
let storeFailures = 0;
|
|
19428
|
+
const attempts = /* @__PURE__ */ new Map();
|
|
19429
|
+
const reportError = (error, conversationId) => {
|
|
19430
|
+
try {
|
|
19431
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)), conversationId);
|
|
19432
|
+
} catch {
|
|
19433
|
+
}
|
|
19434
|
+
};
|
|
19435
|
+
const currentScope = () => {
|
|
19436
|
+
try {
|
|
19437
|
+
const value = typeof options.scope === "function" ? options.scope() : options.scope;
|
|
19438
|
+
return value ?? "private";
|
|
19439
|
+
} catch (error) {
|
|
19440
|
+
reportError(error);
|
|
19441
|
+
return "private";
|
|
19442
|
+
}
|
|
19443
|
+
};
|
|
19444
|
+
function schedule(delay) {
|
|
19445
|
+
if (disposed) return;
|
|
19446
|
+
if (running || timer !== void 0) {
|
|
19447
|
+
if (running) wakeRequested = true;
|
|
19448
|
+
return;
|
|
19449
|
+
}
|
|
19450
|
+
timer = setTimeout(() => {
|
|
19451
|
+
timer = void 0;
|
|
19452
|
+
void drain();
|
|
19453
|
+
}, delay);
|
|
19454
|
+
}
|
|
19455
|
+
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
19456
|
+
let watchdog;
|
|
19457
|
+
try {
|
|
19458
|
+
return await Promise.race([
|
|
19459
|
+
new Promise((resolve, reject) => {
|
|
19460
|
+
const worker = createAutoExtractor({
|
|
19461
|
+
...options,
|
|
19462
|
+
retainCtx: {
|
|
19463
|
+
...options.retainCtx,
|
|
19464
|
+
vaultCtx: {
|
|
19465
|
+
...vault,
|
|
19466
|
+
canWrite: async () => !disposed && await storage.conversationsCollection.query(import_watermelondb12.Q.where("conversation_id", conversationId), import_watermelondb12.Q.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(import_watermelondb12.Q.where("conversation_id", conversationId), import_watermelondb12.Q.where("id", import_watermelondb12.Q.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed
|
|
19467
|
+
}
|
|
19468
|
+
},
|
|
19469
|
+
// Never publish a private queued observation after a mode flip.
|
|
19470
|
+
scope: jobScope,
|
|
19471
|
+
folderId: jobFolderId,
|
|
19472
|
+
cursorStore: void 0,
|
|
19473
|
+
windowSize: 20,
|
|
19474
|
+
maxWindowSize: 20,
|
|
19475
|
+
onTurnComplete: resolve,
|
|
19476
|
+
onError: reject
|
|
19477
|
+
});
|
|
19478
|
+
worker.processTurn(messages, conversationId);
|
|
19479
|
+
worker.dispose();
|
|
19480
|
+
}),
|
|
19481
|
+
new Promise((_resolve, reject) => {
|
|
19482
|
+
watchdog = setTimeout(
|
|
19483
|
+
() => reject(new Error("Extraction did not settle in time; retained for retry")),
|
|
19484
|
+
options.batchTimeoutMs ?? 18e4
|
|
19485
|
+
);
|
|
19486
|
+
})
|
|
19487
|
+
]);
|
|
19488
|
+
} finally {
|
|
19489
|
+
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
19490
|
+
}
|
|
19491
|
+
}
|
|
19492
|
+
async function drain() {
|
|
19493
|
+
if (disposed || running) return;
|
|
19494
|
+
running = true;
|
|
19495
|
+
wakeRequested = false;
|
|
19496
|
+
let retry = false;
|
|
19497
|
+
let scheduleAfterSuccess = false;
|
|
19498
|
+
try {
|
|
19499
|
+
await writes;
|
|
19500
|
+
const pending = await jobs.query(import_watermelondb12.Q.where("owner_key", owner), import_watermelondb12.Q.where("message_ids", import_watermelondb12.Q.notEq("[]"))).fetch();
|
|
19501
|
+
storeFailures = 0;
|
|
19502
|
+
let processed = 0;
|
|
19503
|
+
for (const job of pending) {
|
|
19504
|
+
if (disposed) break;
|
|
19505
|
+
const attempted = attempts.get(job.id) ?? 0;
|
|
19506
|
+
if (attempted >= MAX_ATTEMPTS) continue;
|
|
19507
|
+
if (processed >= MAX_JOBS_PER_PASS) {
|
|
19508
|
+
scheduleAfterSuccess = true;
|
|
19509
|
+
break;
|
|
19510
|
+
}
|
|
19511
|
+
processed++;
|
|
19512
|
+
const conversationId = String(job._getRaw("conversation_id"));
|
|
19513
|
+
try {
|
|
19514
|
+
const conversations = await storage.conversationsCollection.query(import_watermelondb12.Q.where("conversation_id", conversationId), import_watermelondb12.Q.where("is_deleted", false)).fetchCount();
|
|
19515
|
+
if (!conversations) {
|
|
19516
|
+
await database.write(() => job.destroyPermanently());
|
|
19517
|
+
continue;
|
|
19518
|
+
}
|
|
19519
|
+
const ids = idsOf(job).slice(0, 20);
|
|
19520
|
+
const loaded = await Promise.all(ids.map((id) => getMessageOp(storage, id)));
|
|
19521
|
+
const missing = ids.filter((_id, index) => loaded[index] === null);
|
|
19522
|
+
if (missing.length) {
|
|
19523
|
+
if (attempted < MAX_ATTEMPTS - 1)
|
|
19524
|
+
throw new Error("Source messages not yet available; retained for retry");
|
|
19525
|
+
const dropped = new Set(missing);
|
|
19526
|
+
await database.write(
|
|
19527
|
+
() => job.update(
|
|
19528
|
+
(r) => r._setRaw(
|
|
19529
|
+
"message_ids",
|
|
19530
|
+
JSON.stringify(idsOf(job).filter((id) => !dropped.has(id)))
|
|
19531
|
+
)
|
|
19532
|
+
)
|
|
19533
|
+
);
|
|
19534
|
+
attempts.delete(job.id);
|
|
19535
|
+
scheduleAfterSuccess = true;
|
|
19536
|
+
reportError(
|
|
19537
|
+
new Error(
|
|
19538
|
+
`Dropped ${missing.length} unresolvable source id(s) to unblock extraction`
|
|
19539
|
+
),
|
|
19540
|
+
conversationId
|
|
19541
|
+
);
|
|
19542
|
+
continue;
|
|
19543
|
+
}
|
|
19544
|
+
if (loaded.some(
|
|
19545
|
+
(message) => message && (message.decryptionStatus || isEncrypted(message.content))
|
|
19546
|
+
)) {
|
|
19547
|
+
throw new Error("Source messages are locked; retained for retry");
|
|
19548
|
+
}
|
|
19549
|
+
const messages = loaded.flatMap(
|
|
19550
|
+
(m) => m && m.conversationId === conversationId && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
|
|
19551
|
+
);
|
|
19552
|
+
let success = messages.length === 0;
|
|
19553
|
+
if (messages.length) {
|
|
19554
|
+
const result = await extractBatch(
|
|
19555
|
+
messages,
|
|
19556
|
+
conversationId,
|
|
19557
|
+
ids,
|
|
19558
|
+
currentScope() === "private" ? "private" : String(job._getRaw("scope")),
|
|
19559
|
+
job._getRaw("folder_id") ?? null
|
|
19560
|
+
);
|
|
19561
|
+
success = result.failedCount === 0 && result.outcome !== "empty-after-retry";
|
|
19562
|
+
options.onTurnComplete?.(result);
|
|
19563
|
+
}
|
|
19564
|
+
if (!success) throw new Error("Extraction batch incomplete; retained for retry");
|
|
19565
|
+
attempts.delete(job.id);
|
|
19566
|
+
const sequences = /* @__PURE__ */ new Map();
|
|
19567
|
+
for (const message of loaded)
|
|
19568
|
+
if (message && message.messageId > 0)
|
|
19569
|
+
sequences.set(message.uniqueId, message.messageId);
|
|
19570
|
+
await database.write(async () => {
|
|
19571
|
+
const current = idsOf(job);
|
|
19572
|
+
const acknowledged = ids.filter((id) => current.includes(id));
|
|
19573
|
+
if (!acknowledged.length) return;
|
|
19574
|
+
const done = new Set(acknowledged);
|
|
19575
|
+
const remaining = current.filter((id) => !done.has(id));
|
|
19576
|
+
if (remaining.length) {
|
|
19577
|
+
await job.update(
|
|
19578
|
+
(r) => r._setRaw("message_ids", JSON.stringify([...acknowledged.slice(-2), ...remaining]))
|
|
19579
|
+
);
|
|
19580
|
+
} else await job.update((r) => r._setRaw("message_ids", "[]"));
|
|
19581
|
+
const newest = acknowledged[acknowledged.length - 1];
|
|
19582
|
+
await job.update((r) => {
|
|
19583
|
+
r._setRaw("watermark", newest);
|
|
19584
|
+
const sequence = sequences.get(newest);
|
|
19585
|
+
if (sequence !== void 0) {
|
|
19586
|
+
const prior = seqOf(job);
|
|
19587
|
+
r._setRaw(
|
|
19588
|
+
"watermark_seq",
|
|
19589
|
+
prior === void 0 ? sequence : Math.max(prior, sequence)
|
|
19590
|
+
);
|
|
19591
|
+
}
|
|
19592
|
+
});
|
|
19593
|
+
});
|
|
19594
|
+
scheduleAfterSuccess = true;
|
|
19595
|
+
} catch (error) {
|
|
19596
|
+
attempts.set(job.id, attempted + 1);
|
|
19597
|
+
retry = true;
|
|
19598
|
+
reportError(error, conversationId);
|
|
19599
|
+
}
|
|
19600
|
+
}
|
|
19601
|
+
} catch (error) {
|
|
19602
|
+
retry = ++storeFailures < 3;
|
|
19603
|
+
reportError(error);
|
|
19604
|
+
} finally {
|
|
19605
|
+
running = false;
|
|
19606
|
+
const woken = wakeRequested;
|
|
19607
|
+
wakeRequested = false;
|
|
19608
|
+
if (retry || scheduleAfterSuccess || woken)
|
|
19609
|
+
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
19610
|
+
}
|
|
19611
|
+
}
|
|
19612
|
+
schedule(0);
|
|
19613
|
+
return {
|
|
19614
|
+
processTurn(messages, conversationId) {
|
|
19615
|
+
if (disposed || !conversationId || !messages.length) return false;
|
|
19616
|
+
const ids = messages.map((m) => m.id);
|
|
19617
|
+
const scope = currentScope();
|
|
19618
|
+
writes = writes.then(
|
|
19619
|
+
() => database.write(async () => {
|
|
19620
|
+
const existing = await jobs.query(import_watermelondb12.Q.where("owner_key", owner), import_watermelondb12.Q.where("conversation_id", conversationId)).fetch();
|
|
19621
|
+
const job = existing.find(
|
|
19622
|
+
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
19623
|
+
);
|
|
19624
|
+
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
19625
|
+
const rows = await storage.messagesCollection.query(import_watermelondb12.Q.where("id", import_watermelondb12.Q.oneOf(ids))).fetch();
|
|
19626
|
+
const sequences = /* @__PURE__ */ new Map();
|
|
19627
|
+
for (const row of rows) {
|
|
19628
|
+
const sequence = Number(row._getRaw("message_id"));
|
|
19629
|
+
if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
|
|
19630
|
+
}
|
|
19631
|
+
let boundary = -1;
|
|
19632
|
+
let observedSeq = 0;
|
|
19633
|
+
const foreignSources = /* @__PURE__ */ new Set();
|
|
19634
|
+
for (const prior of existing) {
|
|
19635
|
+
const sources = [...idsOf(prior), String(prior._getRaw("watermark") ?? "")];
|
|
19636
|
+
for (const id of sources) {
|
|
19637
|
+
boundary = Math.max(boundary, positions.get(id) ?? -1);
|
|
19638
|
+
if (prior !== job) foreignSources.add(id);
|
|
19639
|
+
}
|
|
19640
|
+
observedSeq = Math.max(observedSeq, seqOf(prior) ?? 0);
|
|
19641
|
+
for (const id of idsOf(prior))
|
|
19642
|
+
observedSeq = Math.max(observedSeq, sequences.get(id) ?? 0);
|
|
19643
|
+
}
|
|
19644
|
+
if (observedSeq > 0)
|
|
19645
|
+
ids.forEach((id, index) => {
|
|
19646
|
+
const sequence = sequences.get(id);
|
|
19647
|
+
if (sequence !== void 0 && sequence <= observedSeq)
|
|
19648
|
+
boundary = Math.max(boundary, index);
|
|
19649
|
+
});
|
|
19650
|
+
if (!existing.length && options.cursorStore) {
|
|
19651
|
+
try {
|
|
19652
|
+
const cursor = options.cursorStore.get(conversationId);
|
|
19653
|
+
if (cursor) boundary = Math.max(boundary, positions.get(cursor) ?? -1);
|
|
19654
|
+
} catch (error) {
|
|
19655
|
+
reportError(error, conversationId);
|
|
19656
|
+
}
|
|
19657
|
+
}
|
|
19658
|
+
if (boundary < 0 && existing.some((prior) => idsOf(prior).length > 0 || seqOf(prior) !== void 0)) {
|
|
19659
|
+
reportError(
|
|
19660
|
+
new Error("Extraction boundary unresolved; skipped rather than re-observing"),
|
|
19661
|
+
conversationId
|
|
19662
|
+
);
|
|
19663
|
+
return;
|
|
19664
|
+
}
|
|
19665
|
+
const start = boundary >= 0 ? boundary + 1 : Math.max(0, ids.length - Math.max(1, options.windowSize ?? 6));
|
|
19666
|
+
if (start >= ids.length) return;
|
|
19667
|
+
const ownWatermark = job?._getRaw("watermark");
|
|
19668
|
+
const atOwnWatermark = !!job && boundary >= 0 && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
|
|
19669
|
+
const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
|
|
19670
|
+
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
|
|
19671
|
+
if (!fresh.length) return;
|
|
19672
|
+
if (job) {
|
|
19673
|
+
await job.update(
|
|
19674
|
+
(r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
|
|
19675
|
+
);
|
|
19676
|
+
attempts.delete(job.id);
|
|
19677
|
+
} else {
|
|
19678
|
+
await jobs.create((r) => {
|
|
19679
|
+
r._setRaw("owner_key", owner);
|
|
19680
|
+
r._setRaw("conversation_id", conversationId);
|
|
19681
|
+
r._setRaw("scope", scope);
|
|
19682
|
+
r._setRaw("folder_id", folderId);
|
|
19683
|
+
r._setRaw("message_ids", JSON.stringify([...new Set(fresh)]));
|
|
19684
|
+
});
|
|
19685
|
+
}
|
|
19686
|
+
})
|
|
19687
|
+
).then(() => schedule(options.debounceMs ?? 2e4)).catch((error) => reportError(error, conversationId));
|
|
19688
|
+
return true;
|
|
19689
|
+
},
|
|
19690
|
+
isProcessing: () => running,
|
|
19691
|
+
dispose() {
|
|
19692
|
+
disposed = true;
|
|
19693
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
19694
|
+
}
|
|
19695
|
+
};
|
|
19696
|
+
}
|
|
19697
|
+
|
|
19139
19698
|
// src/lib/memoryEngine/index.ts
|
|
19140
19699
|
init_chunking();
|
|
19141
19700
|
init_embeddings();
|
|
@@ -22349,13 +22908,13 @@ init_redactor();
|
|
|
22349
22908
|
init_useEncryption();
|
|
22350
22909
|
|
|
22351
22910
|
// src/lib/db/schema.ts
|
|
22352
|
-
var
|
|
22911
|
+
var import_watermelondb21 = require("@nozbe/watermelondb");
|
|
22353
22912
|
var import_migrations2 = require("@nozbe/watermelondb/Schema/migrations");
|
|
22354
22913
|
|
|
22355
22914
|
// src/lib/db/appFiles/models.ts
|
|
22356
|
-
var
|
|
22915
|
+
var import_watermelondb13 = require("@nozbe/watermelondb");
|
|
22357
22916
|
var import_decorators4 = require("@nozbe/watermelondb/decorators");
|
|
22358
|
-
var AppFile = class extends
|
|
22917
|
+
var AppFile = class extends import_watermelondb13.Model {
|
|
22359
22918
|
};
|
|
22360
22919
|
AppFile.table = "app_files";
|
|
22361
22920
|
AppFile.associations = {};
|
|
@@ -22377,9 +22936,9 @@ __decorateClass([
|
|
|
22377
22936
|
], AppFile.prototype, "updatedAt", 2);
|
|
22378
22937
|
|
|
22379
22938
|
// src/lib/db/conversationMemory/models.ts
|
|
22380
|
-
var
|
|
22939
|
+
var import_watermelondb14 = require("@nozbe/watermelondb");
|
|
22381
22940
|
var import_decorators5 = require("@nozbe/watermelondb/decorators");
|
|
22382
|
-
var ConversationMemory = class extends
|
|
22941
|
+
var ConversationMemory = class extends import_watermelondb14.Model {
|
|
22383
22942
|
};
|
|
22384
22943
|
ConversationMemory.table = "conversation_memory";
|
|
22385
22944
|
ConversationMemory.associations = {};
|
|
@@ -22398,9 +22957,9 @@ __decorateClass([
|
|
|
22398
22957
|
], ConversationMemory.prototype, "createdAt", 2);
|
|
22399
22958
|
|
|
22400
22959
|
// src/lib/db/entities/models.ts
|
|
22401
|
-
var
|
|
22960
|
+
var import_watermelondb15 = require("@nozbe/watermelondb");
|
|
22402
22961
|
var import_decorators6 = require("@nozbe/watermelondb/decorators");
|
|
22403
|
-
var Entity = class extends
|
|
22962
|
+
var Entity = class extends import_watermelondb15.Model {
|
|
22404
22963
|
};
|
|
22405
22964
|
Entity.table = "entity";
|
|
22406
22965
|
__decorateClass([
|
|
@@ -22416,7 +22975,7 @@ __decorateClass([
|
|
|
22416
22975
|
__decorateClass([
|
|
22417
22976
|
(0, import_decorators6.date)("updated_at")
|
|
22418
22977
|
], Entity.prototype, "updatedAt", 2);
|
|
22419
|
-
var MemoryEntity = class extends
|
|
22978
|
+
var MemoryEntity = class extends import_watermelondb15.Model {
|
|
22420
22979
|
};
|
|
22421
22980
|
MemoryEntity.table = "memory_entity";
|
|
22422
22981
|
__decorateClass([
|
|
@@ -22433,10 +22992,13 @@ __decorateClass([
|
|
|
22433
22992
|
(0, import_decorators6.date)("created_at")
|
|
22434
22993
|
], MemoryEntity.prototype, "createdAt", 2);
|
|
22435
22994
|
|
|
22995
|
+
// src/lib/db/schema.ts
|
|
22996
|
+
init_models();
|
|
22997
|
+
|
|
22436
22998
|
// src/lib/db/project/models.ts
|
|
22437
|
-
var
|
|
22999
|
+
var import_watermelondb16 = require("@nozbe/watermelondb");
|
|
22438
23000
|
var import_decorators7 = require("@nozbe/watermelondb/decorators");
|
|
22439
|
-
var Project = class extends
|
|
23001
|
+
var Project = class extends import_watermelondb16.Model {
|
|
22440
23002
|
};
|
|
22441
23003
|
Project.table = "projects";
|
|
22442
23004
|
Project.associations = {
|
|
@@ -22459,10 +23021,10 @@ __decorateClass([
|
|
|
22459
23021
|
], Project.prototype, "isDeleted", 2);
|
|
22460
23022
|
|
|
22461
23023
|
// src/lib/db/savedTools/models.ts
|
|
22462
|
-
var
|
|
23024
|
+
var import_watermelondb17 = require("@nozbe/watermelondb");
|
|
22463
23025
|
var import_decorators8 = require("@nozbe/watermelondb/decorators");
|
|
22464
23026
|
var sanitizeParameters = (raw) => raw ?? {};
|
|
22465
|
-
var SavedTool = class extends
|
|
23027
|
+
var SavedTool = class extends import_watermelondb17.Model {
|
|
22466
23028
|
};
|
|
22467
23029
|
SavedTool.table = "saved_tools";
|
|
22468
23030
|
SavedTool.associations = {};
|
|
@@ -22496,9 +23058,9 @@ __decorateClass([
|
|
|
22496
23058
|
], SavedTool.prototype, "isDeleted", 2);
|
|
22497
23059
|
|
|
22498
23060
|
// src/lib/db/settings/models.ts
|
|
22499
|
-
var
|
|
23061
|
+
var import_watermelondb18 = require("@nozbe/watermelondb");
|
|
22500
23062
|
var import_decorators9 = require("@nozbe/watermelondb/decorators");
|
|
22501
|
-
var ModelPreference = class extends
|
|
23063
|
+
var ModelPreference = class extends import_watermelondb18.Model {
|
|
22502
23064
|
};
|
|
22503
23065
|
ModelPreference.table = "modelPreferences";
|
|
22504
23066
|
__decorateClass([
|
|
@@ -22509,9 +23071,9 @@ __decorateClass([
|
|
|
22509
23071
|
], ModelPreference.prototype, "models", 2);
|
|
22510
23072
|
|
|
22511
23073
|
// src/lib/db/userPreferences/models.ts
|
|
22512
|
-
var
|
|
23074
|
+
var import_watermelondb19 = require("@nozbe/watermelondb");
|
|
22513
23075
|
var import_decorators10 = require("@nozbe/watermelondb/decorators");
|
|
22514
|
-
var UserPreference = class extends
|
|
23076
|
+
var UserPreference = class extends import_watermelondb19.Model {
|
|
22515
23077
|
};
|
|
22516
23078
|
UserPreference.table = "userPreferences";
|
|
22517
23079
|
__decorateClass([
|
|
@@ -22540,9 +23102,9 @@ __decorateClass([
|
|
|
22540
23102
|
], UserPreference.prototype, "updatedAt", 2);
|
|
22541
23103
|
|
|
22542
23104
|
// src/lib/db/vaultFolders/models.ts
|
|
22543
|
-
var
|
|
23105
|
+
var import_watermelondb20 = require("@nozbe/watermelondb");
|
|
22544
23106
|
var import_decorators11 = require("@nozbe/watermelondb/decorators");
|
|
22545
|
-
var VaultFolder = class extends
|
|
23107
|
+
var VaultFolder = class extends import_watermelondb20.Model {
|
|
22546
23108
|
};
|
|
22547
23109
|
VaultFolder.table = "vault_folders";
|
|
22548
23110
|
__decorateClass([
|
|
@@ -22569,12 +23131,27 @@ __decorateClass([
|
|
|
22569
23131
|
], VaultFolder.prototype, "context", 2);
|
|
22570
23132
|
|
|
22571
23133
|
// src/lib/db/schema.ts
|
|
22572
|
-
var SDK_SCHEMA_VERSION =
|
|
22573
|
-
var sdkSchema = (0,
|
|
23134
|
+
var SDK_SCHEMA_VERSION = 46;
|
|
23135
|
+
var sdkSchema = (0, import_watermelondb21.appSchema)({
|
|
22574
23136
|
version: SDK_SCHEMA_VERSION,
|
|
22575
23137
|
tables: [
|
|
23138
|
+
(0, import_watermelondb21.tableSchema)({
|
|
23139
|
+
name: "memory_extraction_jobs",
|
|
23140
|
+
columns: [
|
|
23141
|
+
{ name: "owner_key", type: "string", isIndexed: true },
|
|
23142
|
+
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
23143
|
+
{ name: "scope", type: "string" },
|
|
23144
|
+
{ name: "message_ids", type: "string" },
|
|
23145
|
+
{ name: "watermark", type: "string", isOptional: true },
|
|
23146
|
+
// Deletion-proof anchor: history.message_id of the newest acknowledged
|
|
23147
|
+
// source. `watermark` alone is an id, and deleting that message erased
|
|
23148
|
+
// the anchor — see the column note in extractionJobs/models.ts.
|
|
23149
|
+
{ name: "watermark_seq", type: "number", isOptional: true },
|
|
23150
|
+
{ name: "folder_id", type: "string", isOptional: true }
|
|
23151
|
+
]
|
|
23152
|
+
}),
|
|
22576
23153
|
// Chat storage tables
|
|
22577
|
-
(0,
|
|
23154
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22578
23155
|
name: "history",
|
|
22579
23156
|
columns: [
|
|
22580
23157
|
{ name: "message_id", type: "number" },
|
|
@@ -22613,7 +23190,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22613
23190
|
// MessageOrigin — provenance, NOT encrypted (see v44)
|
|
22614
23191
|
]
|
|
22615
23192
|
}),
|
|
22616
|
-
(0,
|
|
23193
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22617
23194
|
name: "conversations",
|
|
22618
23195
|
columns: [
|
|
22619
23196
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
@@ -22635,7 +23212,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22635
23212
|
]
|
|
22636
23213
|
}),
|
|
22637
23214
|
// Project storage table
|
|
22638
|
-
(0,
|
|
23215
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22639
23216
|
name: "projects",
|
|
22640
23217
|
columns: [
|
|
22641
23218
|
{ name: "project_id", type: "string", isIndexed: true },
|
|
@@ -22646,7 +23223,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22646
23223
|
]
|
|
22647
23224
|
}),
|
|
22648
23225
|
// Settings storage tables (deprecated - use userPreferences)
|
|
22649
|
-
(0,
|
|
23226
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22650
23227
|
name: "modelPreferences",
|
|
22651
23228
|
columns: [
|
|
22652
23229
|
{ name: "wallet_address", type: "string", isIndexed: true },
|
|
@@ -22654,7 +23231,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22654
23231
|
]
|
|
22655
23232
|
}),
|
|
22656
23233
|
// Unified user preferences storage
|
|
22657
|
-
(0,
|
|
23234
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22658
23235
|
name: "userPreferences",
|
|
22659
23236
|
columns: [
|
|
22660
23237
|
// Identity
|
|
@@ -22673,7 +23250,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22673
23250
|
]
|
|
22674
23251
|
}),
|
|
22675
23252
|
// Memory vault storage
|
|
22676
|
-
(0,
|
|
23253
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22677
23254
|
name: "memory_vault",
|
|
22678
23255
|
columns: [
|
|
22679
23256
|
{ name: "content", type: "string" },
|
|
@@ -22801,7 +23378,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22801
23378
|
]
|
|
22802
23379
|
}),
|
|
22803
23380
|
// Entity table — canonical names extracted from auto-extraction (W5).
|
|
22804
|
-
(0,
|
|
23381
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22805
23382
|
name: "entity",
|
|
22806
23383
|
columns: [
|
|
22807
23384
|
{ name: "canonical_name", type: "string", isIndexed: true },
|
|
@@ -22811,7 +23388,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22811
23388
|
]
|
|
22812
23389
|
}),
|
|
22813
23390
|
// Many-to-many join: which memories reference which entities.
|
|
22814
|
-
(0,
|
|
23391
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22815
23392
|
name: "memory_entity",
|
|
22816
23393
|
columns: [
|
|
22817
23394
|
{ name: "memory_id", type: "string", isIndexed: true },
|
|
@@ -22821,7 +23398,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22821
23398
|
]
|
|
22822
23399
|
}),
|
|
22823
23400
|
// Vault folder organization
|
|
22824
|
-
(0,
|
|
23401
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22825
23402
|
name: "vault_folders",
|
|
22826
23403
|
columns: [
|
|
22827
23404
|
{ name: "name", type: "string" },
|
|
@@ -22834,7 +23411,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22834
23411
|
]
|
|
22835
23412
|
}),
|
|
22836
23413
|
// Conversation summary cache for progressive history summarization
|
|
22837
|
-
(0,
|
|
23414
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22838
23415
|
name: "conversation_summaries",
|
|
22839
23416
|
columns: [
|
|
22840
23417
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
@@ -22847,7 +23424,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22847
23424
|
]
|
|
22848
23425
|
}),
|
|
22849
23426
|
// Media library storage (images, videos, audio, documents)
|
|
22850
|
-
(0,
|
|
23427
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22851
23428
|
name: "media",
|
|
22852
23429
|
columns: [
|
|
22853
23430
|
// Identity
|
|
@@ -22883,7 +23460,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22883
23460
|
]
|
|
22884
23461
|
}),
|
|
22885
23462
|
// ── App files ─────────────────────────────────────────────────────────
|
|
22886
|
-
(0,
|
|
23463
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22887
23464
|
name: "app_files",
|
|
22888
23465
|
columns: [
|
|
22889
23466
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
@@ -22894,7 +23471,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22894
23471
|
]
|
|
22895
23472
|
}),
|
|
22896
23473
|
// ── Saved tools ──────────────────────────────────────────────────────
|
|
22897
|
-
(0,
|
|
23474
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22898
23475
|
name: "saved_tools",
|
|
22899
23476
|
columns: [
|
|
22900
23477
|
{ name: "name", type: "string" },
|
|
@@ -22910,7 +23487,7 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
22910
23487
|
]
|
|
22911
23488
|
}),
|
|
22912
23489
|
// ── Conversation memories (panel persistence) ────────────────────────
|
|
22913
|
-
(0,
|
|
23490
|
+
(0, import_watermelondb21.tableSchema)({
|
|
22914
23491
|
name: "conversation_memory",
|
|
22915
23492
|
columns: [
|
|
22916
23493
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
@@ -23577,10 +24154,28 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
|
|
|
23577
24154
|
columns: [{ name: "media", type: "string", isOptional: true }]
|
|
23578
24155
|
})
|
|
23579
24156
|
]
|
|
24157
|
+
},
|
|
24158
|
+
{
|
|
24159
|
+
toVersion: 46,
|
|
24160
|
+
steps: [
|
|
24161
|
+
(0, import_migrations2.createTable)({
|
|
24162
|
+
name: "memory_extraction_jobs",
|
|
24163
|
+
columns: [
|
|
24164
|
+
{ name: "owner_key", type: "string", isIndexed: true },
|
|
24165
|
+
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
24166
|
+
{ name: "scope", type: "string" },
|
|
24167
|
+
{ name: "message_ids", type: "string" },
|
|
24168
|
+
{ name: "watermark", type: "string", isOptional: true },
|
|
24169
|
+
{ name: "watermark_seq", type: "number", isOptional: true },
|
|
24170
|
+
{ name: "folder_id", type: "string", isOptional: true }
|
|
24171
|
+
]
|
|
24172
|
+
})
|
|
24173
|
+
]
|
|
23580
24174
|
}
|
|
23581
24175
|
]
|
|
23582
24176
|
});
|
|
23583
24177
|
var sdkModelClasses = [
|
|
24178
|
+
ExtractionJob,
|
|
23584
24179
|
Message,
|
|
23585
24180
|
Conversation,
|
|
23586
24181
|
ConversationSummary,
|
|
@@ -23598,7 +24193,7 @@ var sdkModelClasses = [
|
|
|
23598
24193
|
];
|
|
23599
24194
|
|
|
23600
24195
|
// src/lib/db/manager.ts
|
|
23601
|
-
var
|
|
24196
|
+
var import_watermelondb22 = require("@nozbe/watermelondb");
|
|
23602
24197
|
var DESTRUCTIVE_MIGRATION_VERSION = 8;
|
|
23603
24198
|
var webPlatformStorage = {
|
|
23604
24199
|
getItem: (key) => localStorage.getItem(key),
|
|
@@ -23679,7 +24274,7 @@ var DatabaseManager = class {
|
|
|
23679
24274
|
walletAddress
|
|
23680
24275
|
});
|
|
23681
24276
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
23682
|
-
const database = new
|
|
24277
|
+
const database = new import_watermelondb22.Database({
|
|
23683
24278
|
adapter,
|
|
23684
24279
|
modelClasses: sdkModelClasses
|
|
23685
24280
|
});
|
|
@@ -23758,7 +24353,7 @@ var DatabaseManager = class {
|
|
|
23758
24353
|
};
|
|
23759
24354
|
|
|
23760
24355
|
// src/lib/db/conversationMemory/operations.ts
|
|
23761
|
-
var
|
|
24356
|
+
var import_watermelondb23 = require("@nozbe/watermelondb");
|
|
23762
24357
|
var MAX_PER_CONVERSATION = 200;
|
|
23763
24358
|
function conversationMemoryToStored(row) {
|
|
23764
24359
|
return {
|
|
@@ -23773,7 +24368,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
23773
24368
|
if (!conversationId || items.length === 0) return;
|
|
23774
24369
|
const now = Date.now();
|
|
23775
24370
|
await ctx.database.write(async () => {
|
|
23776
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
24371
|
+
const existing = await ctx.conversationMemoryCollection.query(import_watermelondb23.Q.where("conversation_id", conversationId), import_watermelondb23.Q.sortBy("created_at", import_watermelondb23.Q.asc)).fetch();
|
|
23777
24372
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
23778
24373
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
23779
24374
|
const deduped = [];
|
|
@@ -23808,20 +24403,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
23808
24403
|
}
|
|
23809
24404
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
23810
24405
|
if (!conversationId) return [];
|
|
23811
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
24406
|
+
const rows = await ctx.conversationMemoryCollection.query(import_watermelondb23.Q.where("conversation_id", conversationId), import_watermelondb23.Q.sortBy("created_at", import_watermelondb23.Q.asc)).fetch();
|
|
23812
24407
|
return rows.map(conversationMemoryToStored);
|
|
23813
24408
|
}
|
|
23814
24409
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
23815
24410
|
if (!conversationId) return;
|
|
23816
24411
|
await ctx.database.write(async () => {
|
|
23817
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
24412
|
+
const rows = await ctx.conversationMemoryCollection.query(import_watermelondb23.Q.where("conversation_id", conversationId)).fetch();
|
|
23818
24413
|
if (rows.length === 0) return;
|
|
23819
24414
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
23820
24415
|
});
|
|
23821
24416
|
}
|
|
23822
24417
|
|
|
23823
24418
|
// src/lib/db/vaultFolders/operations.ts
|
|
23824
|
-
var
|
|
24419
|
+
var import_watermelondb24 = require("@nozbe/watermelondb");
|
|
23825
24420
|
function folderToStored(folder) {
|
|
23826
24421
|
return {
|
|
23827
24422
|
uniqueId: folder.id,
|
|
@@ -23846,7 +24441,7 @@ async function createVaultFolderOp(ctx, opts) {
|
|
|
23846
24441
|
return folderToStored(created);
|
|
23847
24442
|
}
|
|
23848
24443
|
async function getAllVaultFoldersOp(ctx) {
|
|
23849
|
-
const results = await ctx.vaultFolderCollection.query(
|
|
24444
|
+
const results = await ctx.vaultFolderCollection.query(import_watermelondb24.Q.where("is_deleted", false), import_watermelondb24.Q.sortBy("created_at", import_watermelondb24.Q.desc)).fetch();
|
|
23850
24445
|
return results.map(folderToStored);
|
|
23851
24446
|
}
|
|
23852
24447
|
async function updateVaultFolderOp(ctx, id, opts) {
|
|
@@ -23855,7 +24450,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
|
|
|
23855
24450
|
if (record.isDeleted) return null;
|
|
23856
24451
|
const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
|
|
23857
24452
|
const updated = await ctx.database.write(async () => {
|
|
23858
|
-
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(
|
|
24453
|
+
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb24.Q.where("folder_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch() : [];
|
|
23859
24454
|
const updates = [];
|
|
23860
24455
|
updates.push(
|
|
23861
24456
|
record.prepareUpdate((r) => {
|
|
@@ -23883,7 +24478,7 @@ async function deleteVaultFolderOp(ctx, id) {
|
|
|
23883
24478
|
const record = await ctx.vaultFolderCollection.find(id);
|
|
23884
24479
|
if (record.isDeleted) return false;
|
|
23885
24480
|
await ctx.database.write(async () => {
|
|
23886
|
-
const memories = await ctx.vaultMemoryCollection.query(
|
|
24481
|
+
const memories = await ctx.vaultMemoryCollection.query(import_watermelondb24.Q.where("folder_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
|
|
23887
24482
|
const preparedMemories = memories.map(
|
|
23888
24483
|
(memory) => memory.prepareUpdate((r) => {
|
|
23889
24484
|
r._setRaw("folder_id", null);
|
|
@@ -23952,7 +24547,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
|
|
|
23952
24547
|
}
|
|
23953
24548
|
}
|
|
23954
24549
|
async function getVaultFolderMemoryCountOp(ctx, folderId) {
|
|
23955
|
-
return await ctx.vaultMemoryCollection.query(
|
|
24550
|
+
return await ctx.vaultMemoryCollection.query(import_watermelondb24.Q.where("folder_id", folderId), import_watermelondb24.Q.where("is_deleted", false)).fetchCount();
|
|
23956
24551
|
}
|
|
23957
24552
|
|
|
23958
24553
|
// src/lib/db/vaultFolders/defaults.ts
|
|
@@ -24966,6 +25561,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
24966
25561
|
WalletPoller,
|
|
24967
25562
|
addConversationMemoriesOp,
|
|
24968
25563
|
archiveVaultMemoryOp,
|
|
25564
|
+
assembleMemoryContext,
|
|
24969
25565
|
backfillMemoryTopicsOp,
|
|
24970
25566
|
buildNotionAuthUrl,
|
|
24971
25567
|
capHopsForDensity,
|
|
@@ -24998,6 +25594,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
24998
25594
|
createChunkVectorCache,
|
|
24999
25595
|
createCryptoPricePreProcessor,
|
|
25000
25596
|
createDecaySweeper,
|
|
25597
|
+
createDurableAutoExtractor,
|
|
25001
25598
|
createLlmDecayClassifier,
|
|
25002
25599
|
createLlmNeighborRefiner,
|
|
25003
25600
|
createMemoryEngineTool,
|
|
@@ -25018,6 +25615,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
25018
25615
|
decodeChunkVector,
|
|
25019
25616
|
decryptConversationTitle,
|
|
25020
25617
|
deleteAllVaultMemoriesForUserOp,
|
|
25618
|
+
deleteMessageOp,
|
|
25021
25619
|
deleteVaultFolderOp,
|
|
25022
25620
|
deleteVaultMemoryOp,
|
|
25023
25621
|
dequantizeEmbedding,
|
|
@@ -25090,6 +25688,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
|
|
|
25090
25688
|
setLogger,
|
|
25091
25689
|
setMemoryVisibilityOp,
|
|
25092
25690
|
shouldChunkMessage,
|
|
25691
|
+
shouldRecallMemory,
|
|
25093
25692
|
stampTopicsExtractedAtOp,
|
|
25094
25693
|
streamCancelPath,
|
|
25095
25694
|
streamReplayPath,
|