@anuma/sdk 6.32.0 → 6.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +456 -249
- package/dist/expo/index.d.mts +434 -170
- package/dist/expo/index.d.ts +434 -170
- package/dist/expo/index.mjs +415 -210
- package/dist/memory/context.d.mts +1 -0
- package/dist/memory/context.d.ts +1 -0
- package/dist/react/index.cjs +465 -303
- package/dist/react/index.d.mts +425 -170
- package/dist/react/index.d.ts +425 -170
- package/dist/react/index.mjs +418 -258
- package/dist/server/index.cjs +423 -216
- package/dist/server/index.d.mts +433 -171
- package/dist/server/index.d.ts +433 -171
- package/dist/server/index.mjs +418 -213
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -7677,7 +7677,13 @@ async function runToolLoop(options) {
|
|
|
7677
7677
|
);
|
|
7678
7678
|
const extra = results.flatMap((r) => Array.isArray(r) ? r : []);
|
|
7679
7679
|
if (extra.length > 0) {
|
|
7680
|
-
|
|
7680
|
+
let userIndex = messages.length - 1;
|
|
7681
|
+
while (userIndex > 0 && messages[userIndex].role !== "user") userIndex--;
|
|
7682
|
+
messages = [
|
|
7683
|
+
...messages.slice(0, userIndex),
|
|
7684
|
+
...await redactBatch(extra),
|
|
7685
|
+
...messages.slice(userIndex)
|
|
7686
|
+
];
|
|
7681
7687
|
}
|
|
7682
7688
|
}
|
|
7683
7689
|
} catch (err) {
|
|
@@ -15267,7 +15273,10 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
|
|
|
15267
15273
|
if (memoryId) cacheRowVector(cache, memoryId, Float32Array.from(embedding), updatedAt, content);
|
|
15268
15274
|
if (vaultCtx && memoryId) {
|
|
15269
15275
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
15270
|
-
updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel
|
|
15276
|
+
updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel, {
|
|
15277
|
+
content,
|
|
15278
|
+
...updatedAt !== void 0 && { updatedAt: updatedAt.getTime() }
|
|
15279
|
+
}).catch(
|
|
15271
15280
|
// Silently swallow – SDK must not use console.*; embedding will be retried on next search
|
|
15272
15281
|
() => {
|
|
15273
15282
|
}
|
|
@@ -18788,6 +18797,349 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
18788
18797
|
};
|
|
18789
18798
|
}
|
|
18790
18799
|
|
|
18800
|
+
// src/lib/memory/store/local.ts
|
|
18801
|
+
import { Q as Q8 } from "@nozbe/watermelondb";
|
|
18802
|
+
|
|
18803
|
+
// src/lib/memory/topicExtract.ts
|
|
18804
|
+
var TOPIC_EXTRACTION_BATCH_SIZE = 10;
|
|
18805
|
+
var MAX_CHARS_PER_MEMORY = 300;
|
|
18806
|
+
var MAX_VOCABULARY_NAMES = 100;
|
|
18807
|
+
var MAX_COMPLETION_TOKENS = 8192;
|
|
18808
|
+
var SYSTEM_PROMPT5 = `You assign topics to saved memories for a personal memory system.
|
|
18809
|
+
|
|
18810
|
+
Each memory is a short statement about the user. For each memory, list the NAMED entities it mentions \u2014 these become the memory's topics, used to connect related memories in a knowledge graph.
|
|
18811
|
+
|
|
18812
|
+
Include only NAMED entities, skip generic/common nouns. A topic must identify a specific thing the user could recognize by name; if it would be equally true of thousands of unrelated memories, leave it out:
|
|
18813
|
+
- SKIP bare generic nouns even when the memory capitalizes them or a calendar entry is titled that way \u2014 "Home", "Work", "Meeting", "Lunch", "Birthday", "Appointment", "Trip", "Today", "Friday", "March" are NOT topics.
|
|
18814
|
+
- KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
|
|
18815
|
+
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
18816
|
+
${ENTITY_KIND_GUIDELINES}
|
|
18817
|
+
|
|
18818
|
+
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
|
|
18819
|
+
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
18820
|
+
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
18821
|
+
No prose.`;
|
|
18822
|
+
async function extractEntitiesForMemories(memories, options) {
|
|
18823
|
+
const out = /* @__PURE__ */ new Map();
|
|
18824
|
+
if (memories.length === 0) return out;
|
|
18825
|
+
const redactor = resolvePiiRedactor(options.piiRedaction);
|
|
18826
|
+
const vocabulary = [];
|
|
18827
|
+
for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
|
|
18828
|
+
vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
|
|
18829
|
+
}
|
|
18830
|
+
const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
|
|
18831
|
+
When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
|
|
18832
|
+
|
|
18833
|
+
` : "";
|
|
18834
|
+
for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
|
|
18835
|
+
const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
|
|
18836
|
+
const rows = [];
|
|
18837
|
+
for (const m of batch) {
|
|
18838
|
+
const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
|
|
18839
|
+
rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
|
|
18840
|
+
}
|
|
18841
|
+
const listing = rows.join("\n");
|
|
18842
|
+
const parsed = await callPortalJsonCompletion({
|
|
18843
|
+
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
18844
|
+
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
18845
|
+
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
18846
|
+
taskType: "memory_topic",
|
|
18847
|
+
...options.endpointOverride !== void 0 && {
|
|
18848
|
+
endpointOverride: options.endpointOverride
|
|
18849
|
+
},
|
|
18850
|
+
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
18851
|
+
systemPrompt: SYSTEM_PROMPT5,
|
|
18852
|
+
userMessage: `${vocabularyNote}Memories:
|
|
18853
|
+
${listing}
|
|
18854
|
+
|
|
18855
|
+
List each memory's named entities.`,
|
|
18856
|
+
tag: "memory/topics",
|
|
18857
|
+
extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
|
|
18858
|
+
...options.fetchFn && { fetchFn: options.fetchFn },
|
|
18859
|
+
...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
|
|
18860
|
+
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
18861
|
+
...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
|
|
18862
|
+
...options.backoffMs && { backoffMs: options.backoffMs }
|
|
18863
|
+
});
|
|
18864
|
+
if (parsed === null) {
|
|
18865
|
+
getLogger().warn(
|
|
18866
|
+
`[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
|
|
18867
|
+
);
|
|
18868
|
+
continue;
|
|
18869
|
+
}
|
|
18870
|
+
const validIds = new Set(batch.map((m) => m.id));
|
|
18871
|
+
const byId = parseTopicResponse(parsed, validIds);
|
|
18872
|
+
if (byId === null) {
|
|
18873
|
+
getLogger().warn(
|
|
18874
|
+
`[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
|
|
18875
|
+
);
|
|
18876
|
+
continue;
|
|
18877
|
+
}
|
|
18878
|
+
for (const m of batch) {
|
|
18879
|
+
const entities = byId.get(m.id);
|
|
18880
|
+
if (entities === void 0) {
|
|
18881
|
+
continue;
|
|
18882
|
+
}
|
|
18883
|
+
out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
|
|
18884
|
+
}
|
|
18885
|
+
}
|
|
18886
|
+
return out;
|
|
18887
|
+
}
|
|
18888
|
+
function restoreEntities(entities, redactor) {
|
|
18889
|
+
return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
|
|
18890
|
+
(e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
|
|
18891
|
+
);
|
|
18892
|
+
}
|
|
18893
|
+
function parseTopicResponse(parsed, validIds) {
|
|
18894
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
18895
|
+
const list = parsed.memories;
|
|
18896
|
+
if (!Array.isArray(list)) return null;
|
|
18897
|
+
const out = /* @__PURE__ */ new Map();
|
|
18898
|
+
for (const raw of list) {
|
|
18899
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
18900
|
+
const obj = raw;
|
|
18901
|
+
if (typeof obj.id !== "string") continue;
|
|
18902
|
+
const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
|
|
18903
|
+
if (!validIds.has(id) || out.has(id)) continue;
|
|
18904
|
+
const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
|
|
18905
|
+
out.set(id, entities);
|
|
18906
|
+
}
|
|
18907
|
+
return out;
|
|
18908
|
+
}
|
|
18909
|
+
var DEGRADED_TOPIC_SKIP = {
|
|
18910
|
+
excluded: false,
|
|
18911
|
+
"link-declined": false,
|
|
18912
|
+
"stamp-declined": false,
|
|
18913
|
+
"llm-unanswered": true,
|
|
18914
|
+
unreadable: true,
|
|
18915
|
+
"not-found": true,
|
|
18916
|
+
"link-failed": true
|
|
18917
|
+
};
|
|
18918
|
+
function isDegradedTopicSkip(reason) {
|
|
18919
|
+
return DEGRADED_TOPIC_SKIP[reason] === true;
|
|
18920
|
+
}
|
|
18921
|
+
async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
18922
|
+
const entityCtx = ctx.entityCtx;
|
|
18923
|
+
if (!entityCtx) {
|
|
18924
|
+
throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
|
|
18925
|
+
}
|
|
18926
|
+
const log = getLogger();
|
|
18927
|
+
const extractedAt = options.now ?? Date.now();
|
|
18928
|
+
const skippedIds = [];
|
|
18929
|
+
const skippedReasons = /* @__PURE__ */ new Map();
|
|
18930
|
+
const skip = (id, reason) => {
|
|
18931
|
+
if (skippedReasons.has(id)) return;
|
|
18932
|
+
skippedIds.push(id);
|
|
18933
|
+
skippedReasons.set(id, reason);
|
|
18934
|
+
};
|
|
18935
|
+
const inputs = [];
|
|
18936
|
+
for (const id of new Set(memoryIds)) {
|
|
18937
|
+
let record;
|
|
18938
|
+
try {
|
|
18939
|
+
record = await ctx.vaultMemoryCollection.find(id);
|
|
18940
|
+
} catch (err) {
|
|
18941
|
+
log.warn("[memory/topics] vault lookup failed for extraction", err);
|
|
18942
|
+
skip(id, "not-found");
|
|
18943
|
+
continue;
|
|
18944
|
+
}
|
|
18945
|
+
if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
|
|
18946
|
+
skip(id, "excluded");
|
|
18947
|
+
continue;
|
|
18948
|
+
}
|
|
18949
|
+
try {
|
|
18950
|
+
const stored = await vaultMemoryToStored(
|
|
18951
|
+
record,
|
|
18952
|
+
ctx.walletAddress,
|
|
18953
|
+
ctx.signMessage,
|
|
18954
|
+
ctx.embeddedWalletSigner
|
|
18955
|
+
);
|
|
18956
|
+
inputs.push({ id, content: stored.content });
|
|
18957
|
+
} catch (err) {
|
|
18958
|
+
log.warn("[memory/topics] failed to load memory for extraction", err);
|
|
18959
|
+
skip(id, "unreadable");
|
|
18960
|
+
}
|
|
18961
|
+
}
|
|
18962
|
+
const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
|
|
18963
|
+
const toStamp = [];
|
|
18964
|
+
for (const input of inputs) {
|
|
18965
|
+
const entities = entitiesByMemory.get(input.id);
|
|
18966
|
+
if (entities === void 0) {
|
|
18967
|
+
skip(input.id, "llm-unanswered");
|
|
18968
|
+
continue;
|
|
18969
|
+
}
|
|
18970
|
+
try {
|
|
18971
|
+
const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
|
|
18972
|
+
if (linked === null) {
|
|
18973
|
+
skip(input.id, "link-declined");
|
|
18974
|
+
entitiesByMemory.delete(input.id);
|
|
18975
|
+
continue;
|
|
18976
|
+
}
|
|
18977
|
+
} catch (err) {
|
|
18978
|
+
log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
|
|
18979
|
+
skip(input.id, "link-failed");
|
|
18980
|
+
entitiesByMemory.delete(input.id);
|
|
18981
|
+
continue;
|
|
18982
|
+
}
|
|
18983
|
+
toStamp.push(input.id);
|
|
18984
|
+
}
|
|
18985
|
+
const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
|
|
18986
|
+
const stampedSet = new Set(stampedIds);
|
|
18987
|
+
for (const id of toStamp) {
|
|
18988
|
+
if (!stampedSet.has(id)) {
|
|
18989
|
+
skip(id, "stamp-declined");
|
|
18990
|
+
entitiesByMemory.delete(id);
|
|
18991
|
+
}
|
|
18992
|
+
}
|
|
18993
|
+
return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
|
|
18994
|
+
}
|
|
18995
|
+
|
|
18996
|
+
// src/lib/memory/store/local.ts
|
|
18997
|
+
function createLocalMemoryStore(options) {
|
|
18998
|
+
const { database, userId } = options;
|
|
18999
|
+
const entityCtx = {
|
|
19000
|
+
database,
|
|
19001
|
+
entityCollection: database.get("entity"),
|
|
19002
|
+
memoryEntityCollection: database.get("memory_entity"),
|
|
19003
|
+
...userId !== void 0 && { userId },
|
|
19004
|
+
...options.allowUnscopedRows !== void 0 && {
|
|
19005
|
+
allowUnscopedRows: options.allowUnscopedRows
|
|
19006
|
+
}
|
|
19007
|
+
};
|
|
19008
|
+
const vaultCtx = {
|
|
19009
|
+
database,
|
|
19010
|
+
vaultMemoryCollection: database.get("memory_vault"),
|
|
19011
|
+
walletAddress: options.walletAddress,
|
|
19012
|
+
signMessage: options.signMessage,
|
|
19013
|
+
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
19014
|
+
...userId !== void 0 && { userId },
|
|
19015
|
+
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
19016
|
+
// Deletes cascade to memory_entity, so the graph lane never serves a
|
|
19017
|
+
// deleted memory's id.
|
|
19018
|
+
entityCtx
|
|
19019
|
+
};
|
|
19020
|
+
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
19021
|
+
const ownedBy = userId !== void 0 ? [Q8.where("user_id", userId)] : [];
|
|
19022
|
+
const watchedColumns = [
|
|
19023
|
+
"content",
|
|
19024
|
+
"scope",
|
|
19025
|
+
"updated_at",
|
|
19026
|
+
"fact_type",
|
|
19027
|
+
"event_time_start",
|
|
19028
|
+
"event_time_end",
|
|
19029
|
+
"event_time_kind",
|
|
19030
|
+
"archived_at",
|
|
19031
|
+
"trust_tier",
|
|
19032
|
+
"superseded_by",
|
|
19033
|
+
"visibility",
|
|
19034
|
+
"published_at",
|
|
19035
|
+
"geohash",
|
|
19036
|
+
"topics",
|
|
19037
|
+
"topics_user_managed",
|
|
19038
|
+
"media",
|
|
19039
|
+
"source"
|
|
19040
|
+
];
|
|
19041
|
+
const embedInBackground = (memory) => {
|
|
19042
|
+
eagerEmbedContent(
|
|
19043
|
+
memory.content,
|
|
19044
|
+
options.embeddingOptions,
|
|
19045
|
+
vaultCache,
|
|
19046
|
+
vaultCtx,
|
|
19047
|
+
memory.uniqueId,
|
|
19048
|
+
memory.updatedAt
|
|
19049
|
+
).catch((err) => {
|
|
19050
|
+
getLogger().warn("[memory/store] Failed to embed memory:", err);
|
|
19051
|
+
});
|
|
19052
|
+
};
|
|
19053
|
+
return {
|
|
19054
|
+
list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
|
|
19055
|
+
get: (id) => getVaultMemoryOp(vaultCtx, id),
|
|
19056
|
+
listArchived: async () => {
|
|
19057
|
+
const ids = await vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), Q8.where("archived_at", Q8.notEq(null)), ...ownedBy).fetchIds();
|
|
19058
|
+
if (ids.length === 0) return [];
|
|
19059
|
+
const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
|
|
19060
|
+
return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
|
|
19061
|
+
},
|
|
19062
|
+
memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
|
|
19063
|
+
topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
|
|
19064
|
+
create: async (input) => {
|
|
19065
|
+
const created = await createVaultMemoryOp(vaultCtx, input);
|
|
19066
|
+
if (input.embedding === void 0) embedInBackground(created);
|
|
19067
|
+
return created;
|
|
19068
|
+
},
|
|
19069
|
+
createMany: async (inputs) => {
|
|
19070
|
+
const created = await createVaultMemoriesBatchOp(vaultCtx, inputs);
|
|
19071
|
+
created.forEach((memory, i) => {
|
|
19072
|
+
if (inputs[i].embedding === void 0) embedInBackground(memory);
|
|
19073
|
+
});
|
|
19074
|
+
return created;
|
|
19075
|
+
},
|
|
19076
|
+
update: async (id, patch) => {
|
|
19077
|
+
const reembed = patch.embedding === void 0;
|
|
19078
|
+
const updated = await updateVaultMemoryOp(
|
|
19079
|
+
vaultCtx,
|
|
19080
|
+
id,
|
|
19081
|
+
reembed ? { ...patch, embedding: null } : patch
|
|
19082
|
+
);
|
|
19083
|
+
if (!updated) return null;
|
|
19084
|
+
vaultCache.delete(id);
|
|
19085
|
+
if (reembed) embedInBackground(updated);
|
|
19086
|
+
return updated;
|
|
19087
|
+
},
|
|
19088
|
+
delete: async (id) => {
|
|
19089
|
+
const deleted = await deleteVaultMemoryOp(vaultCtx, id);
|
|
19090
|
+
if (deleted) vaultCache.delete(id);
|
|
19091
|
+
return deleted;
|
|
19092
|
+
},
|
|
19093
|
+
supersede: (id, supersededById) => supersedeVaultMemoryOp(vaultCtx, id, supersededById),
|
|
19094
|
+
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
19095
|
+
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
19096
|
+
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
19097
|
+
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
19098
|
+
const owned = await vaultCtx.vaultMemoryCollection.query(Q8.where("id", memoryId), Q8.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
19099
|
+
return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
|
|
19100
|
+
}),
|
|
19101
|
+
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
19102
|
+
recall: (query, recallOptions) => recall(
|
|
19103
|
+
query,
|
|
19104
|
+
{ vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions, vaultCache },
|
|
19105
|
+
{ ...recallOptions, types: ["fact"] }
|
|
19106
|
+
),
|
|
19107
|
+
retain: (content, retainOptions) => retain(
|
|
19108
|
+
content,
|
|
19109
|
+
{ vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
|
|
19110
|
+
retainOptions
|
|
19111
|
+
),
|
|
19112
|
+
subscribe: (onChange, subscribeOptions) => {
|
|
19113
|
+
const afterFirst = () => {
|
|
19114
|
+
let first = true;
|
|
19115
|
+
return () => {
|
|
19116
|
+
if (first) first = false;
|
|
19117
|
+
else onChange();
|
|
19118
|
+
};
|
|
19119
|
+
};
|
|
19120
|
+
const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), ...ownedBy).observeWithColumns(
|
|
19121
|
+
subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
|
|
19122
|
+
);
|
|
19123
|
+
const subscriptions = [memories.subscribe(afterFirst())];
|
|
19124
|
+
if (subscribeOptions?.topics) {
|
|
19125
|
+
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
|
|
19126
|
+
subscriptions.push(
|
|
19127
|
+
entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
|
|
19128
|
+
);
|
|
19129
|
+
}
|
|
19130
|
+
return () => subscriptions.forEach((s) => s.unsubscribe());
|
|
19131
|
+
},
|
|
19132
|
+
maintenance: {
|
|
19133
|
+
createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
|
|
19134
|
+
getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
|
|
19135
|
+
extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
|
|
19136
|
+
stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
|
|
19137
|
+
relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
|
|
19138
|
+
backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
|
|
19139
|
+
}
|
|
19140
|
+
};
|
|
19141
|
+
}
|
|
19142
|
+
|
|
18791
19143
|
// src/lib/memory/synthesizeProfile.ts
|
|
18792
19144
|
var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
|
|
18793
19145
|
var DEFAULT_FACET_RECALL_LIMIT = 20;
|
|
@@ -19315,199 +19667,6 @@ function normalizeInterests(values) {
|
|
|
19315
19667
|
return out.length > 0 ? out : void 0;
|
|
19316
19668
|
}
|
|
19317
19669
|
|
|
19318
|
-
// src/lib/memory/topicExtract.ts
|
|
19319
|
-
var TOPIC_EXTRACTION_BATCH_SIZE = 10;
|
|
19320
|
-
var MAX_CHARS_PER_MEMORY = 300;
|
|
19321
|
-
var MAX_VOCABULARY_NAMES = 100;
|
|
19322
|
-
var MAX_COMPLETION_TOKENS = 8192;
|
|
19323
|
-
var SYSTEM_PROMPT5 = `You assign topics to saved memories for a personal memory system.
|
|
19324
|
-
|
|
19325
|
-
Each memory is a short statement about the user. For each memory, list the NAMED entities it mentions \u2014 these become the memory's topics, used to connect related memories in a knowledge graph.
|
|
19326
|
-
|
|
19327
|
-
Include only NAMED entities, skip generic/common nouns. A topic must identify a specific thing the user could recognize by name; if it would be equally true of thousands of unrelated memories, leave it out:
|
|
19328
|
-
- SKIP bare generic nouns even when the memory capitalizes them or a calendar entry is titled that way \u2014 "Home", "Work", "Meeting", "Lunch", "Birthday", "Appointment", "Trip", "Today", "Friday", "March" are NOT topics.
|
|
19329
|
-
- KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
|
|
19330
|
-
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
19331
|
-
${ENTITY_KIND_GUIDELINES}
|
|
19332
|
-
|
|
19333
|
-
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
|
|
19334
|
-
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
19335
|
-
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
19336
|
-
No prose.`;
|
|
19337
|
-
async function extractEntitiesForMemories(memories, options) {
|
|
19338
|
-
const out = /* @__PURE__ */ new Map();
|
|
19339
|
-
if (memories.length === 0) return out;
|
|
19340
|
-
const redactor = resolvePiiRedactor(options.piiRedaction);
|
|
19341
|
-
const vocabulary = [];
|
|
19342
|
-
for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
|
|
19343
|
-
vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
|
|
19344
|
-
}
|
|
19345
|
-
const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
|
|
19346
|
-
When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
|
|
19347
|
-
|
|
19348
|
-
` : "";
|
|
19349
|
-
for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
|
|
19350
|
-
const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
|
|
19351
|
-
const rows = [];
|
|
19352
|
-
for (const m of batch) {
|
|
19353
|
-
const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
|
|
19354
|
-
rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
|
|
19355
|
-
}
|
|
19356
|
-
const listing = rows.join("\n");
|
|
19357
|
-
const parsed = await callPortalJsonCompletion({
|
|
19358
|
-
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
19359
|
-
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
19360
|
-
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
19361
|
-
taskType: "memory_topic",
|
|
19362
|
-
...options.endpointOverride !== void 0 && {
|
|
19363
|
-
endpointOverride: options.endpointOverride
|
|
19364
|
-
},
|
|
19365
|
-
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
19366
|
-
systemPrompt: SYSTEM_PROMPT5,
|
|
19367
|
-
userMessage: `${vocabularyNote}Memories:
|
|
19368
|
-
${listing}
|
|
19369
|
-
|
|
19370
|
-
List each memory's named entities.`,
|
|
19371
|
-
tag: "memory/topics",
|
|
19372
|
-
extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
|
|
19373
|
-
...options.fetchFn && { fetchFn: options.fetchFn },
|
|
19374
|
-
...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
|
|
19375
|
-
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
19376
|
-
...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
|
|
19377
|
-
...options.backoffMs && { backoffMs: options.backoffMs }
|
|
19378
|
-
});
|
|
19379
|
-
if (parsed === null) {
|
|
19380
|
-
getLogger().warn(
|
|
19381
|
-
`[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
|
|
19382
|
-
);
|
|
19383
|
-
continue;
|
|
19384
|
-
}
|
|
19385
|
-
const validIds = new Set(batch.map((m) => m.id));
|
|
19386
|
-
const byId = parseTopicResponse(parsed, validIds);
|
|
19387
|
-
if (byId === null) {
|
|
19388
|
-
getLogger().warn(
|
|
19389
|
-
`[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
|
|
19390
|
-
);
|
|
19391
|
-
continue;
|
|
19392
|
-
}
|
|
19393
|
-
for (const m of batch) {
|
|
19394
|
-
const entities = byId.get(m.id);
|
|
19395
|
-
if (entities === void 0) {
|
|
19396
|
-
continue;
|
|
19397
|
-
}
|
|
19398
|
-
out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
|
|
19399
|
-
}
|
|
19400
|
-
}
|
|
19401
|
-
return out;
|
|
19402
|
-
}
|
|
19403
|
-
function restoreEntities(entities, redactor) {
|
|
19404
|
-
return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
|
|
19405
|
-
(e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
|
|
19406
|
-
);
|
|
19407
|
-
}
|
|
19408
|
-
function parseTopicResponse(parsed, validIds) {
|
|
19409
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
19410
|
-
const list = parsed.memories;
|
|
19411
|
-
if (!Array.isArray(list)) return null;
|
|
19412
|
-
const out = /* @__PURE__ */ new Map();
|
|
19413
|
-
for (const raw of list) {
|
|
19414
|
-
if (typeof raw !== "object" || raw === null) continue;
|
|
19415
|
-
const obj = raw;
|
|
19416
|
-
if (typeof obj.id !== "string") continue;
|
|
19417
|
-
const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
|
|
19418
|
-
if (!validIds.has(id) || out.has(id)) continue;
|
|
19419
|
-
const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
|
|
19420
|
-
out.set(id, entities);
|
|
19421
|
-
}
|
|
19422
|
-
return out;
|
|
19423
|
-
}
|
|
19424
|
-
var DEGRADED_TOPIC_SKIP = {
|
|
19425
|
-
excluded: false,
|
|
19426
|
-
"link-declined": false,
|
|
19427
|
-
"stamp-declined": false,
|
|
19428
|
-
"llm-unanswered": true,
|
|
19429
|
-
unreadable: true,
|
|
19430
|
-
"not-found": true,
|
|
19431
|
-
"link-failed": true
|
|
19432
|
-
};
|
|
19433
|
-
function isDegradedTopicSkip(reason) {
|
|
19434
|
-
return DEGRADED_TOPIC_SKIP[reason] === true;
|
|
19435
|
-
}
|
|
19436
|
-
async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
19437
|
-
const entityCtx = ctx.entityCtx;
|
|
19438
|
-
if (!entityCtx) {
|
|
19439
|
-
throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
|
|
19440
|
-
}
|
|
19441
|
-
const log = getLogger();
|
|
19442
|
-
const extractedAt = options.now ?? Date.now();
|
|
19443
|
-
const skippedIds = [];
|
|
19444
|
-
const skippedReasons = /* @__PURE__ */ new Map();
|
|
19445
|
-
const skip = (id, reason) => {
|
|
19446
|
-
if (skippedReasons.has(id)) return;
|
|
19447
|
-
skippedIds.push(id);
|
|
19448
|
-
skippedReasons.set(id, reason);
|
|
19449
|
-
};
|
|
19450
|
-
const inputs = [];
|
|
19451
|
-
for (const id of new Set(memoryIds)) {
|
|
19452
|
-
let record;
|
|
19453
|
-
try {
|
|
19454
|
-
record = await ctx.vaultMemoryCollection.find(id);
|
|
19455
|
-
} catch (err) {
|
|
19456
|
-
log.warn("[memory/topics] vault lookup failed for extraction", err);
|
|
19457
|
-
skip(id, "not-found");
|
|
19458
|
-
continue;
|
|
19459
|
-
}
|
|
19460
|
-
if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
|
|
19461
|
-
skip(id, "excluded");
|
|
19462
|
-
continue;
|
|
19463
|
-
}
|
|
19464
|
-
try {
|
|
19465
|
-
const stored = await vaultMemoryToStored(
|
|
19466
|
-
record,
|
|
19467
|
-
ctx.walletAddress,
|
|
19468
|
-
ctx.signMessage,
|
|
19469
|
-
ctx.embeddedWalletSigner
|
|
19470
|
-
);
|
|
19471
|
-
inputs.push({ id, content: stored.content });
|
|
19472
|
-
} catch (err) {
|
|
19473
|
-
log.warn("[memory/topics] failed to load memory for extraction", err);
|
|
19474
|
-
skip(id, "unreadable");
|
|
19475
|
-
}
|
|
19476
|
-
}
|
|
19477
|
-
const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
|
|
19478
|
-
const toStamp = [];
|
|
19479
|
-
for (const input of inputs) {
|
|
19480
|
-
const entities = entitiesByMemory.get(input.id);
|
|
19481
|
-
if (entities === void 0) {
|
|
19482
|
-
skip(input.id, "llm-unanswered");
|
|
19483
|
-
continue;
|
|
19484
|
-
}
|
|
19485
|
-
try {
|
|
19486
|
-
const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
|
|
19487
|
-
if (linked === null) {
|
|
19488
|
-
skip(input.id, "link-declined");
|
|
19489
|
-
entitiesByMemory.delete(input.id);
|
|
19490
|
-
continue;
|
|
19491
|
-
}
|
|
19492
|
-
} catch (err) {
|
|
19493
|
-
log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
|
|
19494
|
-
skip(input.id, "link-failed");
|
|
19495
|
-
entitiesByMemory.delete(input.id);
|
|
19496
|
-
continue;
|
|
19497
|
-
}
|
|
19498
|
-
toStamp.push(input.id);
|
|
19499
|
-
}
|
|
19500
|
-
const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
|
|
19501
|
-
const stampedSet = new Set(stampedIds);
|
|
19502
|
-
for (const id of toStamp) {
|
|
19503
|
-
if (!stampedSet.has(id)) {
|
|
19504
|
-
skip(id, "stamp-declined");
|
|
19505
|
-
entitiesByMemory.delete(id);
|
|
19506
|
-
}
|
|
19507
|
-
}
|
|
19508
|
-
return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
|
|
19509
|
-
}
|
|
19510
|
-
|
|
19511
19670
|
// src/lib/memory/verifySupport.ts
|
|
19512
19671
|
var DEFAULT_MODEL5 = "inclusionai/ling-2.6-flash";
|
|
19513
19672
|
var DEFAULT_ATTEMPTS3 = 2;
|
|
@@ -19898,7 +20057,7 @@ async function assembleMemoryContext(options) {
|
|
|
19898
20057
|
}
|
|
19899
20058
|
|
|
19900
20059
|
// src/lib/memory/durableExtraction.ts
|
|
19901
|
-
import { Q as
|
|
20060
|
+
import { Q as Q9 } from "@nozbe/watermelondb";
|
|
19902
20061
|
var MAX_JOBS_PER_PASS = 3;
|
|
19903
20062
|
var MAX_ATTEMPTS = 3;
|
|
19904
20063
|
var MAX_FAILED_SESSIONS = 3;
|
|
@@ -20045,7 +20204,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20045
20204
|
...options.retainCtx,
|
|
20046
20205
|
vaultCtx: {
|
|
20047
20206
|
...vault,
|
|
20048
|
-
canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(
|
|
20207
|
+
canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q9.where("conversation_id", conversationId), Q9.where("id", Q9.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed && !cancelled
|
|
20049
20208
|
}
|
|
20050
20209
|
},
|
|
20051
20210
|
// The model follows the job's scope, not the mode alive at drain time.
|
|
@@ -20187,7 +20346,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20187
20346
|
let scheduleAfterSuccess = false;
|
|
20188
20347
|
try {
|
|
20189
20348
|
await writes;
|
|
20190
|
-
const pending = await jobs.query(
|
|
20349
|
+
const pending = await jobs.query(Q9.where("owner_key", owner), Q9.where("message_ids", Q9.notEq("[]"))).fetch();
|
|
20191
20350
|
storeFailures = 0;
|
|
20192
20351
|
let processed = 0;
|
|
20193
20352
|
for (const job of pending) {
|
|
@@ -20203,7 +20362,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20203
20362
|
let ids = [];
|
|
20204
20363
|
let loaded = [];
|
|
20205
20364
|
try {
|
|
20206
|
-
const conversations = await storage.conversationsCollection.query(
|
|
20365
|
+
const conversations = await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount();
|
|
20207
20366
|
if (!conversations) {
|
|
20208
20367
|
await database.write(() => job.destroyPermanently());
|
|
20209
20368
|
continue;
|
|
@@ -20320,12 +20479,12 @@ function createDurableAutoExtractor(options) {
|
|
|
20320
20479
|
const scope = currentScope();
|
|
20321
20480
|
writes = writes.then(
|
|
20322
20481
|
() => database.write(async () => {
|
|
20323
|
-
const existing = await jobs.query(
|
|
20482
|
+
const existing = await jobs.query(Q9.where("owner_key", owner), Q9.where("conversation_id", conversationId)).fetch();
|
|
20324
20483
|
const job = existing.find(
|
|
20325
20484
|
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
20326
20485
|
);
|
|
20327
20486
|
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
20328
|
-
const rows = await storage.messagesCollection.query(
|
|
20487
|
+
const rows = await storage.messagesCollection.query(Q9.where("id", Q9.oneOf(ids))).fetch();
|
|
20329
20488
|
const sequences = /* @__PURE__ */ new Map();
|
|
20330
20489
|
for (const row of rows) {
|
|
20331
20490
|
const sequence = Number(row._getRaw("message_id"));
|
|
@@ -25980,7 +26139,7 @@ function useDatabaseManager(walletAddress, manager) {
|
|
|
25980
26139
|
}
|
|
25981
26140
|
|
|
25982
26141
|
// src/lib/db/project/operations.ts
|
|
25983
|
-
import { Q as
|
|
26142
|
+
import { Q as Q10 } from "@nozbe/watermelondb";
|
|
25984
26143
|
|
|
25985
26144
|
// src/lib/db/project/types.ts
|
|
25986
26145
|
function generateProjectId() {
|
|
@@ -26011,15 +26170,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
|
|
|
26011
26170
|
return projectToStored(created);
|
|
26012
26171
|
}
|
|
26013
26172
|
async function getProjectOp(ctx, id) {
|
|
26014
|
-
const results = await ctx.projectsCollection.query(
|
|
26173
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26015
26174
|
return results.length > 0 ? projectToStored(results[0]) : null;
|
|
26016
26175
|
}
|
|
26017
26176
|
async function getProjectsOp(ctx) {
|
|
26018
|
-
const results = await ctx.projectsCollection.query(
|
|
26177
|
+
const results = await ctx.projectsCollection.query(Q10.where("is_deleted", false), Q10.sortBy("created_at", Q10.desc)).fetch();
|
|
26019
26178
|
return results.map(projectToStored);
|
|
26020
26179
|
}
|
|
26021
26180
|
async function updateProjectNameOp(ctx, id, name) {
|
|
26022
|
-
const results = await ctx.projectsCollection.query(
|
|
26181
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26023
26182
|
if (results.length > 0) {
|
|
26024
26183
|
await ctx.database.write(async () => {
|
|
26025
26184
|
await results[0].update((proj) => {
|
|
@@ -26031,7 +26190,7 @@ async function updateProjectNameOp(ctx, id, name) {
|
|
|
26031
26190
|
return false;
|
|
26032
26191
|
}
|
|
26033
26192
|
async function updateProjectOp(ctx, id, opts) {
|
|
26034
|
-
const results = await ctx.projectsCollection.query(
|
|
26193
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26035
26194
|
if (results.length > 0) {
|
|
26036
26195
|
await ctx.database.write(async () => {
|
|
26037
26196
|
await results[0].update((proj) => {
|
|
@@ -26043,7 +26202,7 @@ async function updateProjectOp(ctx, id, opts) {
|
|
|
26043
26202
|
return false;
|
|
26044
26203
|
}
|
|
26045
26204
|
async function deleteProjectOp(ctx, id) {
|
|
26046
|
-
const results = await ctx.projectsCollection.query(
|
|
26205
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26047
26206
|
if (results.length > 0) {
|
|
26048
26207
|
await ctx.database.write(async () => {
|
|
26049
26208
|
await results[0].update((proj) => {
|
|
@@ -26056,18 +26215,18 @@ async function deleteProjectOp(ctx, id) {
|
|
|
26056
26215
|
}
|
|
26057
26216
|
async function getProjectConversationsOp(ctx, projectId) {
|
|
26058
26217
|
const results = await ctx.conversationsCollection.query(
|
|
26059
|
-
|
|
26060
|
-
|
|
26061
|
-
|
|
26218
|
+
Q10.where("project_id", projectId),
|
|
26219
|
+
Q10.where("is_deleted", false),
|
|
26220
|
+
Q10.sortBy("created_at", Q10.desc)
|
|
26062
26221
|
).fetch();
|
|
26063
26222
|
return results.map(conversationToStoredRaw);
|
|
26064
26223
|
}
|
|
26065
26224
|
async function getProjectConversationCountOp(ctx, projectId) {
|
|
26066
|
-
return await ctx.conversationsCollection.query(
|
|
26225
|
+
return await ctx.conversationsCollection.query(Q10.where("project_id", projectId), Q10.where("is_deleted", false)).fetchCount();
|
|
26067
26226
|
}
|
|
26068
26227
|
|
|
26069
26228
|
// src/react/useFiles.ts
|
|
26070
|
-
import { Q as
|
|
26229
|
+
import { Q as Q11 } from "@nozbe/watermelondb";
|
|
26071
26230
|
import { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState5 } from "react";
|
|
26072
26231
|
function useFiles(options) {
|
|
26073
26232
|
const { database, walletAddress } = options;
|
|
@@ -26085,7 +26244,7 @@ function useFiles(options) {
|
|
|
26085
26244
|
setIsLoading(true);
|
|
26086
26245
|
try {
|
|
26087
26246
|
const coll = database.get("media");
|
|
26088
|
-
await coll.query(
|
|
26247
|
+
await coll.query(Q11.take(1)).fetch();
|
|
26089
26248
|
setMediaCollection(coll);
|
|
26090
26249
|
setIsReady(true);
|
|
26091
26250
|
} catch (error) {
|
|
@@ -26493,7 +26652,7 @@ function useFiles(options) {
|
|
|
26493
26652
|
}
|
|
26494
26653
|
|
|
26495
26654
|
// src/react/useProjects.ts
|
|
26496
|
-
import { Q as
|
|
26655
|
+
import { Q as Q12 } from "@nozbe/watermelondb";
|
|
26497
26656
|
import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo6, useState as useState6 } from "react";
|
|
26498
26657
|
function useProjects(options) {
|
|
26499
26658
|
const { database, initialProjectId } = options;
|
|
@@ -26515,7 +26674,7 @@ function useProjects(options) {
|
|
|
26515
26674
|
conversations: convColl?.table
|
|
26516
26675
|
});
|
|
26517
26676
|
getLogger().debug("[useProjects] Running test query on projects table...");
|
|
26518
|
-
const testResult = await projColl.query(
|
|
26677
|
+
const testResult = await projColl.query(Q12.take(1)).fetch();
|
|
26519
26678
|
getLogger().debug(
|
|
26520
26679
|
"[useProjects] Test query succeeded, found",
|
|
26521
26680
|
testResult.length,
|
|
@@ -26602,7 +26761,7 @@ function useProjects(options) {
|
|
|
26602
26761
|
if (!projectsCollection) {
|
|
26603
26762
|
return;
|
|
26604
26763
|
}
|
|
26605
|
-
const subscription = projectsCollection.query(
|
|
26764
|
+
const subscription = projectsCollection.query(Q12.where("is_deleted", false)).observe().subscribe((records) => {
|
|
26606
26765
|
setProjects(records.map(projectToStored));
|
|
26607
26766
|
});
|
|
26608
26767
|
return () => subscription.unsubscribe();
|
|
@@ -26725,7 +26884,7 @@ function useProjects(options) {
|
|
|
26725
26884
|
}
|
|
26726
26885
|
|
|
26727
26886
|
// src/lib/db/settings/operations.ts
|
|
26728
|
-
import { Q as
|
|
26887
|
+
import { Q as Q13 } from "@nozbe/watermelondb";
|
|
26729
26888
|
function modelPreferenceToStored(preference) {
|
|
26730
26889
|
return {
|
|
26731
26890
|
uniqueId: preference.id,
|
|
@@ -26734,12 +26893,12 @@ function modelPreferenceToStored(preference) {
|
|
|
26734
26893
|
};
|
|
26735
26894
|
}
|
|
26736
26895
|
async function getModelPreferenceOp(ctx, walletAddress) {
|
|
26737
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26896
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26738
26897
|
return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
|
|
26739
26898
|
}
|
|
26740
26899
|
async function setModelPreferenceOp(ctx, walletAddress, models) {
|
|
26741
26900
|
const result = await ctx.database.write(async () => {
|
|
26742
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26901
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26743
26902
|
if (results.length > 0) {
|
|
26744
26903
|
const preference = results[0];
|
|
26745
26904
|
await preference.update((pref) => {
|
|
@@ -26757,7 +26916,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
|
|
|
26757
26916
|
return modelPreferenceToStored(result);
|
|
26758
26917
|
}
|
|
26759
26918
|
async function deleteModelPreferenceOp(ctx, walletAddress) {
|
|
26760
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26919
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26761
26920
|
if (results.length === 0) return false;
|
|
26762
26921
|
await ctx.database.write(async () => {
|
|
26763
26922
|
await results[0].destroyPermanently();
|
|
@@ -26781,7 +26940,7 @@ var settingsStorageSchema = appSchema3({
|
|
|
26781
26940
|
});
|
|
26782
26941
|
|
|
26783
26942
|
// src/lib/db/vaultFolders/operations.ts
|
|
26784
|
-
import { Q as
|
|
26943
|
+
import { Q as Q14 } from "@nozbe/watermelondb";
|
|
26785
26944
|
function folderToStored(folder) {
|
|
26786
26945
|
return {
|
|
26787
26946
|
uniqueId: folder.id,
|
|
@@ -26806,7 +26965,7 @@ async function createVaultFolderOp(ctx, opts) {
|
|
|
26806
26965
|
return folderToStored(created);
|
|
26807
26966
|
}
|
|
26808
26967
|
async function getAllVaultFoldersOp(ctx) {
|
|
26809
|
-
const results = await ctx.vaultFolderCollection.query(
|
|
26968
|
+
const results = await ctx.vaultFolderCollection.query(Q14.where("is_deleted", false), Q14.sortBy("created_at", Q14.desc)).fetch();
|
|
26810
26969
|
return results.map(folderToStored);
|
|
26811
26970
|
}
|
|
26812
26971
|
async function updateVaultFolderOp(ctx, id, opts) {
|
|
@@ -26815,7 +26974,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
|
|
|
26815
26974
|
if (record.isDeleted) return null;
|
|
26816
26975
|
const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
|
|
26817
26976
|
const updated = await ctx.database.write(async () => {
|
|
26818
|
-
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(
|
|
26977
|
+
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch() : [];
|
|
26819
26978
|
const updates = [];
|
|
26820
26979
|
updates.push(
|
|
26821
26980
|
record.prepareUpdate((r) => {
|
|
@@ -26843,7 +27002,7 @@ async function deleteVaultFolderOp(ctx, id) {
|
|
|
26843
27002
|
const record = await ctx.vaultFolderCollection.find(id);
|
|
26844
27003
|
if (record.isDeleted) return false;
|
|
26845
27004
|
await ctx.database.write(async () => {
|
|
26846
|
-
const memories = await ctx.vaultMemoryCollection.query(
|
|
27005
|
+
const memories = await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch();
|
|
26847
27006
|
const preparedMemories = memories.map(
|
|
26848
27007
|
(memory) => memory.prepareUpdate((r) => {
|
|
26849
27008
|
r._setRaw("folder_id", null);
|
|
@@ -26912,7 +27071,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
|
|
|
26912
27071
|
}
|
|
26913
27072
|
}
|
|
26914
27073
|
async function getVaultFolderMemoryCountOp(ctx, folderId) {
|
|
26915
|
-
return await ctx.vaultMemoryCollection.query(
|
|
27074
|
+
return await ctx.vaultMemoryCollection.query(Q14.where("folder_id", folderId), Q14.where("is_deleted", false)).fetchCount();
|
|
26916
27075
|
}
|
|
26917
27076
|
|
|
26918
27077
|
// src/lib/db/vaultFolders/defaults.ts
|
|
@@ -26958,7 +27117,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
|
|
|
26958
27117
|
import { useCallback as useCallback7, useMemo as useMemo7, useSyncExternalStore } from "react";
|
|
26959
27118
|
|
|
26960
27119
|
// src/lib/db/userPreferences/operations.ts
|
|
26961
|
-
import { Q as
|
|
27120
|
+
import { Q as Q15 } from "@nozbe/watermelondb";
|
|
26962
27121
|
function userPreferenceToStored(preference) {
|
|
26963
27122
|
return {
|
|
26964
27123
|
uniqueId: preference.id,
|
|
@@ -26973,7 +27132,7 @@ function userPreferenceToStored(preference) {
|
|
|
26973
27132
|
};
|
|
26974
27133
|
}
|
|
26975
27134
|
async function getUserPreferenceOp(ctx, walletAddress) {
|
|
26976
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27135
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
26977
27136
|
return results.length > 0 ? userPreferenceToStored(results[0]) : null;
|
|
26978
27137
|
}
|
|
26979
27138
|
async function createUserPreferenceOp(ctx, opts) {
|
|
@@ -26993,7 +27152,7 @@ async function createUserPreferenceOp(ctx, opts) {
|
|
|
26993
27152
|
return userPreferenceToStored(created);
|
|
26994
27153
|
}
|
|
26995
27154
|
async function updateUserPreferenceOp(ctx, walletAddress, opts) {
|
|
26996
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27155
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
26997
27156
|
if (results.length === 0) return null;
|
|
26998
27157
|
const preference = results[0];
|
|
26999
27158
|
await ctx.database.write(async () => {
|
|
@@ -27021,7 +27180,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
|
|
|
27021
27180
|
async function setUserPreferenceOp(ctx, walletAddress, opts) {
|
|
27022
27181
|
const now = Date.now();
|
|
27023
27182
|
const result = await ctx.database.write(async () => {
|
|
27024
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27183
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27025
27184
|
if (results.length > 0) {
|
|
27026
27185
|
const preference = results[0];
|
|
27027
27186
|
await preference.update((pref) => {
|
|
@@ -27069,7 +27228,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
|
|
|
27069
27228
|
return updateUserPreferenceOp(ctx, walletAddress, { models });
|
|
27070
27229
|
}
|
|
27071
27230
|
async function deleteUserPreferenceOp(ctx, walletAddress) {
|
|
27072
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27231
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27073
27232
|
if (results.length === 0) return false;
|
|
27074
27233
|
await ctx.database.write(async () => {
|
|
27075
27234
|
await results[0].destroyPermanently();
|
|
@@ -27084,9 +27243,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
|
|
|
27084
27243
|
if (existing) {
|
|
27085
27244
|
return existing;
|
|
27086
27245
|
}
|
|
27087
|
-
const modelResults = await ctx.modelPreferencesCollection.query(
|
|
27246
|
+
const modelResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27088
27247
|
const personalityKey = `${walletAddress}_personality_settings`;
|
|
27089
|
-
const personalityResults = await ctx.modelPreferencesCollection.query(
|
|
27248
|
+
const personalityResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", personalityKey)).fetch();
|
|
27090
27249
|
if (modelResults.length === 0 && personalityResults.length === 0) {
|
|
27091
27250
|
return null;
|
|
27092
27251
|
}
|
|
@@ -27192,7 +27351,7 @@ var SLIDER_CONFIG = [
|
|
|
27192
27351
|
];
|
|
27193
27352
|
|
|
27194
27353
|
// src/react/userSettingsStore.ts
|
|
27195
|
-
import { Q as
|
|
27354
|
+
import { Q as Q16 } from "@nozbe/watermelondb";
|
|
27196
27355
|
var EMPTY_SNAPSHOT = Object.freeze({
|
|
27197
27356
|
modelPreference: null,
|
|
27198
27357
|
userPreference: null,
|
|
@@ -27254,7 +27413,7 @@ async function startLoad(entry, walletAddress) {
|
|
|
27254
27413
|
}
|
|
27255
27414
|
function startObserve(entry, walletAddress) {
|
|
27256
27415
|
let isInitialEmission = true;
|
|
27257
|
-
entry.observeSub = entry.storageCtx.userPreferencesCollection.query(
|
|
27416
|
+
entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q16.where("wallet_address", walletAddress)).observeWithColumns([
|
|
27258
27417
|
"nickname",
|
|
27259
27418
|
"occupation",
|
|
27260
27419
|
"description",
|
|
@@ -27518,7 +27677,7 @@ function useSettings(options) {
|
|
|
27518
27677
|
}
|
|
27519
27678
|
|
|
27520
27679
|
// src/lib/db/appFiles/operations.ts
|
|
27521
|
-
import { Q as
|
|
27680
|
+
import { Q as Q17 } from "@nozbe/watermelondb";
|
|
27522
27681
|
|
|
27523
27682
|
// src/utils/paths.ts
|
|
27524
27683
|
function normalizePath(p) {
|
|
@@ -27544,7 +27703,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
|
|
|
27544
27703
|
const normalized = normalizePath(path);
|
|
27545
27704
|
const now = Date.now();
|
|
27546
27705
|
const result = await ctx.database.write(async () => {
|
|
27547
|
-
const existing = await ctx.appFilesCollection.query(
|
|
27706
|
+
const existing = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27548
27707
|
if (existing.length > 0) {
|
|
27549
27708
|
await existing[0].update((f) => {
|
|
27550
27709
|
f._setRaw("content", content);
|
|
@@ -27564,11 +27723,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
|
|
|
27564
27723
|
}
|
|
27565
27724
|
async function getAppFileOp(ctx, conversationId, path) {
|
|
27566
27725
|
const normalized = normalizePath(path);
|
|
27567
|
-
const results = await ctx.appFilesCollection.query(
|
|
27726
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27568
27727
|
return results.length > 0 ? appFileToStored(results[0]) : null;
|
|
27569
27728
|
}
|
|
27570
27729
|
async function getAppFilesOp(ctx, conversationId) {
|
|
27571
|
-
const results = await ctx.appFilesCollection.query(
|
|
27730
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
|
|
27572
27731
|
return results.map(appFileToStored);
|
|
27573
27732
|
}
|
|
27574
27733
|
async function getAppFileMapOp(ctx, conversationId) {
|
|
@@ -27579,7 +27738,7 @@ async function getAppFileMapOp(ctx, conversationId) {
|
|
|
27579
27738
|
}
|
|
27580
27739
|
async function deleteAppFileOp(ctx, conversationId, path) {
|
|
27581
27740
|
const normalized = normalizePath(path);
|
|
27582
|
-
const results = await ctx.appFilesCollection.query(
|
|
27741
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27583
27742
|
if (results.length === 0) return false;
|
|
27584
27743
|
await ctx.database.write(async () => {
|
|
27585
27744
|
await results[0].destroyPermanently();
|
|
@@ -27587,7 +27746,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
|
|
|
27587
27746
|
return true;
|
|
27588
27747
|
}
|
|
27589
27748
|
async function deleteAllAppFilesOp(ctx, conversationId) {
|
|
27590
|
-
const results = await ctx.appFilesCollection.query(
|
|
27749
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
|
|
27591
27750
|
if (results.length === 0) return;
|
|
27592
27751
|
await ctx.database.write(async () => {
|
|
27593
27752
|
const batch = results.map((file) => file.prepareDestroyPermanently());
|
|
@@ -27596,7 +27755,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
|
|
|
27596
27755
|
}
|
|
27597
27756
|
|
|
27598
27757
|
// src/lib/db/conversationMemory/operations.ts
|
|
27599
|
-
import { Q as
|
|
27758
|
+
import { Q as Q18 } from "@nozbe/watermelondb";
|
|
27600
27759
|
var MAX_PER_CONVERSATION = 200;
|
|
27601
27760
|
function conversationMemoryToStored(row) {
|
|
27602
27761
|
return {
|
|
@@ -27611,7 +27770,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
27611
27770
|
if (!conversationId || items.length === 0) return;
|
|
27612
27771
|
const now = Date.now();
|
|
27613
27772
|
await ctx.database.write(async () => {
|
|
27614
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
27773
|
+
const existing = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
|
|
27615
27774
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
27616
27775
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
27617
27776
|
const deduped = [];
|
|
@@ -27646,20 +27805,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
27646
27805
|
}
|
|
27647
27806
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
27648
27807
|
if (!conversationId) return [];
|
|
27649
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
27808
|
+
const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
|
|
27650
27809
|
return rows.map(conversationMemoryToStored);
|
|
27651
27810
|
}
|
|
27652
27811
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
27653
27812
|
if (!conversationId) return;
|
|
27654
27813
|
await ctx.database.write(async () => {
|
|
27655
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
27814
|
+
const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId)).fetch();
|
|
27656
27815
|
if (rows.length === 0) return;
|
|
27657
27816
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
27658
27817
|
});
|
|
27659
27818
|
}
|
|
27660
27819
|
|
|
27661
27820
|
// src/lib/db/savedTools/operations.ts
|
|
27662
|
-
import { Q as
|
|
27821
|
+
import { Q as Q19 } from "@nozbe/watermelondb";
|
|
27663
27822
|
function savedToolToStored(tool) {
|
|
27664
27823
|
return {
|
|
27665
27824
|
uniqueId: tool.id,
|
|
@@ -27692,7 +27851,7 @@ async function createSavedToolOp(ctx, opts) {
|
|
|
27692
27851
|
return savedToolToStored(created);
|
|
27693
27852
|
}
|
|
27694
27853
|
async function getAllSavedToolsOp(ctx) {
|
|
27695
|
-
const results = await ctx.savedToolsCollection.query(
|
|
27854
|
+
const results = await ctx.savedToolsCollection.query(Q19.where("is_deleted", false), Q19.sortBy("created_at", Q19.desc)).fetch();
|
|
27696
27855
|
return results.map(savedToolToStored);
|
|
27697
27856
|
}
|
|
27698
27857
|
async function getSavedToolByIdOp(ctx, uniqueId) {
|
|
@@ -30348,8 +30507,8 @@ function createDropboxFileIndex(backupFolder) {
|
|
|
30348
30507
|
};
|
|
30349
30508
|
}
|
|
30350
30509
|
async function readLocalUpdatedAt(database, conversationId) {
|
|
30351
|
-
const { Q:
|
|
30352
|
-
const records = await database.get("conversations").query(
|
|
30510
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
30511
|
+
const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
|
|
30353
30512
|
const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
|
|
30354
30513
|
return match ? match.updatedAt : null;
|
|
30355
30514
|
}
|
|
@@ -30405,9 +30564,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
|
|
|
30405
30564
|
}
|
|
30406
30565
|
async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
|
|
30407
30566
|
await deps.requestEncryptionKey(userAddress);
|
|
30408
|
-
const { Q:
|
|
30567
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
30409
30568
|
const conversationsCollection = database.get("conversations");
|
|
30410
|
-
const records = await conversationsCollection.query(
|
|
30569
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
30411
30570
|
const conversations = records.map(conversationToStoredRaw);
|
|
30412
30571
|
const total = conversations.length;
|
|
30413
30572
|
if (total === 0) {
|
|
@@ -31089,8 +31248,8 @@ function createDriveFileIndex(folderId) {
|
|
|
31089
31248
|
};
|
|
31090
31249
|
}
|
|
31091
31250
|
async function readLocalUpdatedAt2(database, conversationId) {
|
|
31092
|
-
const { Q:
|
|
31093
|
-
const records = await database.get("conversations").query(
|
|
31251
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31252
|
+
const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
|
|
31094
31253
|
const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
|
|
31095
31254
|
return match ? match.updatedAt : null;
|
|
31096
31255
|
}
|
|
@@ -31170,9 +31329,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
|
|
|
31170
31329
|
}
|
|
31171
31330
|
const { folderId, token: activeToken } = folderResult;
|
|
31172
31331
|
const fileIndex = createDriveFileIndex(folderId);
|
|
31173
|
-
const { Q:
|
|
31332
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31174
31333
|
const conversationsCollection = database.get("conversations");
|
|
31175
|
-
const records = await conversationsCollection.query(
|
|
31334
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
31176
31335
|
const conversations = records.map(conversationToStoredRaw);
|
|
31177
31336
|
const total = conversations.length;
|
|
31178
31337
|
if (total === 0) {
|
|
@@ -31757,9 +31916,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
|
|
|
31757
31916
|
const filename = `${conversationId}.json`;
|
|
31758
31917
|
const existingFile = await findICloudFile(filename);
|
|
31759
31918
|
if (existingFile) {
|
|
31760
|
-
const { Q:
|
|
31919
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31761
31920
|
const conversationsCollection = database.get("conversations");
|
|
31762
|
-
const records = await conversationsCollection.query(
|
|
31921
|
+
const records = await conversationsCollection.query(Q20.where("conversation_id", conversationId)).fetch();
|
|
31763
31922
|
if (records.length > 0) {
|
|
31764
31923
|
const conversation = conversationToStoredRaw(records[0]);
|
|
31765
31924
|
const localUpdated = conversation.updatedAt.getTime();
|
|
@@ -31789,9 +31948,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
|
|
|
31789
31948
|
}
|
|
31790
31949
|
async function performICloudExport(database, userAddress, deps, onProgress) {
|
|
31791
31950
|
await deps.requestEncryptionKey(userAddress);
|
|
31792
|
-
const { Q:
|
|
31951
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31793
31952
|
const conversationsCollection = database.get("conversations");
|
|
31794
|
-
const records = await conversationsCollection.query(
|
|
31953
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
31795
31954
|
const conversations = records.map(conversationToStoredRaw);
|
|
31796
31955
|
const total = conversations.length;
|
|
31797
31956
|
if (total === 0) {
|
|
@@ -35766,6 +35925,7 @@ export {
|
|
|
35766
35925
|
createGitHubTools,
|
|
35767
35926
|
createLlmDecayClassifier,
|
|
35768
35927
|
createLlmNeighborRefiner,
|
|
35928
|
+
createLocalMemoryStore,
|
|
35769
35929
|
createMediaBatchOp,
|
|
35770
35930
|
createMediaOp,
|
|
35771
35931
|
createMemoryEngineTool,
|