@anuma/sdk 6.32.0 → 6.33.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/index.cjs +449 -248
- package/dist/expo/index.d.mts +433 -169
- package/dist/expo/index.d.ts +433 -169
- package/dist/expo/index.mjs +408 -209
- package/dist/memory/context.d.mts +1 -0
- package/dist/memory/context.d.ts +1 -0
- package/dist/react/index.cjs +458 -302
- package/dist/react/index.d.mts +424 -169
- package/dist/react/index.d.ts +424 -169
- package/dist/react/index.mjs +411 -257
- package/dist/server/index.cjs +416 -215
- package/dist/server/index.d.mts +431 -169
- package/dist/server/index.d.ts +431 -169
- package/dist/server/index.mjs +411 -212
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -15267,7 +15267,10 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
|
|
|
15267
15267
|
if (memoryId) cacheRowVector(cache, memoryId, Float32Array.from(embedding), updatedAt, content);
|
|
15268
15268
|
if (vaultCtx && memoryId) {
|
|
15269
15269
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
15270
|
-
updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel
|
|
15270
|
+
updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel, {
|
|
15271
|
+
content,
|
|
15272
|
+
...updatedAt !== void 0 && { updatedAt: updatedAt.getTime() }
|
|
15273
|
+
}).catch(
|
|
15271
15274
|
// Silently swallow – SDK must not use console.*; embedding will be retried on next search
|
|
15272
15275
|
() => {
|
|
15273
15276
|
}
|
|
@@ -18788,6 +18791,349 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
18788
18791
|
};
|
|
18789
18792
|
}
|
|
18790
18793
|
|
|
18794
|
+
// src/lib/memory/store/local.ts
|
|
18795
|
+
import { Q as Q8 } from "@nozbe/watermelondb";
|
|
18796
|
+
|
|
18797
|
+
// src/lib/memory/topicExtract.ts
|
|
18798
|
+
var TOPIC_EXTRACTION_BATCH_SIZE = 10;
|
|
18799
|
+
var MAX_CHARS_PER_MEMORY = 300;
|
|
18800
|
+
var MAX_VOCABULARY_NAMES = 100;
|
|
18801
|
+
var MAX_COMPLETION_TOKENS = 8192;
|
|
18802
|
+
var SYSTEM_PROMPT5 = `You assign topics to saved memories for a personal memory system.
|
|
18803
|
+
|
|
18804
|
+
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.
|
|
18805
|
+
|
|
18806
|
+
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:
|
|
18807
|
+
- 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.
|
|
18808
|
+
- KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
|
|
18809
|
+
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
18810
|
+
${ENTITY_KIND_GUIDELINES}
|
|
18811
|
+
|
|
18812
|
+
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
|
|
18813
|
+
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
18814
|
+
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
18815
|
+
No prose.`;
|
|
18816
|
+
async function extractEntitiesForMemories(memories, options) {
|
|
18817
|
+
const out = /* @__PURE__ */ new Map();
|
|
18818
|
+
if (memories.length === 0) return out;
|
|
18819
|
+
const redactor = resolvePiiRedactor(options.piiRedaction);
|
|
18820
|
+
const vocabulary = [];
|
|
18821
|
+
for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
|
|
18822
|
+
vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
|
|
18823
|
+
}
|
|
18824
|
+
const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
|
|
18825
|
+
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".
|
|
18826
|
+
|
|
18827
|
+
` : "";
|
|
18828
|
+
for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
|
|
18829
|
+
const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
|
|
18830
|
+
const rows = [];
|
|
18831
|
+
for (const m of batch) {
|
|
18832
|
+
const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
|
|
18833
|
+
rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
|
|
18834
|
+
}
|
|
18835
|
+
const listing = rows.join("\n");
|
|
18836
|
+
const parsed = await callPortalJsonCompletion({
|
|
18837
|
+
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
18838
|
+
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
18839
|
+
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
18840
|
+
taskType: "memory_topic",
|
|
18841
|
+
...options.endpointOverride !== void 0 && {
|
|
18842
|
+
endpointOverride: options.endpointOverride
|
|
18843
|
+
},
|
|
18844
|
+
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
18845
|
+
systemPrompt: SYSTEM_PROMPT5,
|
|
18846
|
+
userMessage: `${vocabularyNote}Memories:
|
|
18847
|
+
${listing}
|
|
18848
|
+
|
|
18849
|
+
List each memory's named entities.`,
|
|
18850
|
+
tag: "memory/topics",
|
|
18851
|
+
extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
|
|
18852
|
+
...options.fetchFn && { fetchFn: options.fetchFn },
|
|
18853
|
+
...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
|
|
18854
|
+
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
18855
|
+
...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
|
|
18856
|
+
...options.backoffMs && { backoffMs: options.backoffMs }
|
|
18857
|
+
});
|
|
18858
|
+
if (parsed === null) {
|
|
18859
|
+
getLogger().warn(
|
|
18860
|
+
`[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
|
|
18861
|
+
);
|
|
18862
|
+
continue;
|
|
18863
|
+
}
|
|
18864
|
+
const validIds = new Set(batch.map((m) => m.id));
|
|
18865
|
+
const byId = parseTopicResponse(parsed, validIds);
|
|
18866
|
+
if (byId === null) {
|
|
18867
|
+
getLogger().warn(
|
|
18868
|
+
`[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
|
|
18869
|
+
);
|
|
18870
|
+
continue;
|
|
18871
|
+
}
|
|
18872
|
+
for (const m of batch) {
|
|
18873
|
+
const entities = byId.get(m.id);
|
|
18874
|
+
if (entities === void 0) {
|
|
18875
|
+
continue;
|
|
18876
|
+
}
|
|
18877
|
+
out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
|
|
18878
|
+
}
|
|
18879
|
+
}
|
|
18880
|
+
return out;
|
|
18881
|
+
}
|
|
18882
|
+
function restoreEntities(entities, redactor) {
|
|
18883
|
+
return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
|
|
18884
|
+
(e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
|
|
18885
|
+
);
|
|
18886
|
+
}
|
|
18887
|
+
function parseTopicResponse(parsed, validIds) {
|
|
18888
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
18889
|
+
const list = parsed.memories;
|
|
18890
|
+
if (!Array.isArray(list)) return null;
|
|
18891
|
+
const out = /* @__PURE__ */ new Map();
|
|
18892
|
+
for (const raw of list) {
|
|
18893
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
18894
|
+
const obj = raw;
|
|
18895
|
+
if (typeof obj.id !== "string") continue;
|
|
18896
|
+
const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
|
|
18897
|
+
if (!validIds.has(id) || out.has(id)) continue;
|
|
18898
|
+
const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
|
|
18899
|
+
out.set(id, entities);
|
|
18900
|
+
}
|
|
18901
|
+
return out;
|
|
18902
|
+
}
|
|
18903
|
+
var DEGRADED_TOPIC_SKIP = {
|
|
18904
|
+
excluded: false,
|
|
18905
|
+
"link-declined": false,
|
|
18906
|
+
"stamp-declined": false,
|
|
18907
|
+
"llm-unanswered": true,
|
|
18908
|
+
unreadable: true,
|
|
18909
|
+
"not-found": true,
|
|
18910
|
+
"link-failed": true
|
|
18911
|
+
};
|
|
18912
|
+
function isDegradedTopicSkip(reason) {
|
|
18913
|
+
return DEGRADED_TOPIC_SKIP[reason] === true;
|
|
18914
|
+
}
|
|
18915
|
+
async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
18916
|
+
const entityCtx = ctx.entityCtx;
|
|
18917
|
+
if (!entityCtx) {
|
|
18918
|
+
throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
|
|
18919
|
+
}
|
|
18920
|
+
const log = getLogger();
|
|
18921
|
+
const extractedAt = options.now ?? Date.now();
|
|
18922
|
+
const skippedIds = [];
|
|
18923
|
+
const skippedReasons = /* @__PURE__ */ new Map();
|
|
18924
|
+
const skip = (id, reason) => {
|
|
18925
|
+
if (skippedReasons.has(id)) return;
|
|
18926
|
+
skippedIds.push(id);
|
|
18927
|
+
skippedReasons.set(id, reason);
|
|
18928
|
+
};
|
|
18929
|
+
const inputs = [];
|
|
18930
|
+
for (const id of new Set(memoryIds)) {
|
|
18931
|
+
let record;
|
|
18932
|
+
try {
|
|
18933
|
+
record = await ctx.vaultMemoryCollection.find(id);
|
|
18934
|
+
} catch (err) {
|
|
18935
|
+
log.warn("[memory/topics] vault lookup failed for extraction", err);
|
|
18936
|
+
skip(id, "not-found");
|
|
18937
|
+
continue;
|
|
18938
|
+
}
|
|
18939
|
+
if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
|
|
18940
|
+
skip(id, "excluded");
|
|
18941
|
+
continue;
|
|
18942
|
+
}
|
|
18943
|
+
try {
|
|
18944
|
+
const stored = await vaultMemoryToStored(
|
|
18945
|
+
record,
|
|
18946
|
+
ctx.walletAddress,
|
|
18947
|
+
ctx.signMessage,
|
|
18948
|
+
ctx.embeddedWalletSigner
|
|
18949
|
+
);
|
|
18950
|
+
inputs.push({ id, content: stored.content });
|
|
18951
|
+
} catch (err) {
|
|
18952
|
+
log.warn("[memory/topics] failed to load memory for extraction", err);
|
|
18953
|
+
skip(id, "unreadable");
|
|
18954
|
+
}
|
|
18955
|
+
}
|
|
18956
|
+
const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
|
|
18957
|
+
const toStamp = [];
|
|
18958
|
+
for (const input of inputs) {
|
|
18959
|
+
const entities = entitiesByMemory.get(input.id);
|
|
18960
|
+
if (entities === void 0) {
|
|
18961
|
+
skip(input.id, "llm-unanswered");
|
|
18962
|
+
continue;
|
|
18963
|
+
}
|
|
18964
|
+
try {
|
|
18965
|
+
const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
|
|
18966
|
+
if (linked === null) {
|
|
18967
|
+
skip(input.id, "link-declined");
|
|
18968
|
+
entitiesByMemory.delete(input.id);
|
|
18969
|
+
continue;
|
|
18970
|
+
}
|
|
18971
|
+
} catch (err) {
|
|
18972
|
+
log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
|
|
18973
|
+
skip(input.id, "link-failed");
|
|
18974
|
+
entitiesByMemory.delete(input.id);
|
|
18975
|
+
continue;
|
|
18976
|
+
}
|
|
18977
|
+
toStamp.push(input.id);
|
|
18978
|
+
}
|
|
18979
|
+
const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
|
|
18980
|
+
const stampedSet = new Set(stampedIds);
|
|
18981
|
+
for (const id of toStamp) {
|
|
18982
|
+
if (!stampedSet.has(id)) {
|
|
18983
|
+
skip(id, "stamp-declined");
|
|
18984
|
+
entitiesByMemory.delete(id);
|
|
18985
|
+
}
|
|
18986
|
+
}
|
|
18987
|
+
return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
|
|
18988
|
+
}
|
|
18989
|
+
|
|
18990
|
+
// src/lib/memory/store/local.ts
|
|
18991
|
+
function createLocalMemoryStore(options) {
|
|
18992
|
+
const { database, userId } = options;
|
|
18993
|
+
const entityCtx = {
|
|
18994
|
+
database,
|
|
18995
|
+
entityCollection: database.get("entity"),
|
|
18996
|
+
memoryEntityCollection: database.get("memory_entity"),
|
|
18997
|
+
...userId !== void 0 && { userId },
|
|
18998
|
+
...options.allowUnscopedRows !== void 0 && {
|
|
18999
|
+
allowUnscopedRows: options.allowUnscopedRows
|
|
19000
|
+
}
|
|
19001
|
+
};
|
|
19002
|
+
const vaultCtx = {
|
|
19003
|
+
database,
|
|
19004
|
+
vaultMemoryCollection: database.get("memory_vault"),
|
|
19005
|
+
walletAddress: options.walletAddress,
|
|
19006
|
+
signMessage: options.signMessage,
|
|
19007
|
+
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
19008
|
+
...userId !== void 0 && { userId },
|
|
19009
|
+
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
19010
|
+
// Deletes cascade to memory_entity, so the graph lane never serves a
|
|
19011
|
+
// deleted memory's id.
|
|
19012
|
+
entityCtx
|
|
19013
|
+
};
|
|
19014
|
+
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
19015
|
+
const ownedBy = userId !== void 0 ? [Q8.where("user_id", userId)] : [];
|
|
19016
|
+
const watchedColumns = [
|
|
19017
|
+
"content",
|
|
19018
|
+
"scope",
|
|
19019
|
+
"updated_at",
|
|
19020
|
+
"fact_type",
|
|
19021
|
+
"event_time_start",
|
|
19022
|
+
"event_time_end",
|
|
19023
|
+
"event_time_kind",
|
|
19024
|
+
"archived_at",
|
|
19025
|
+
"trust_tier",
|
|
19026
|
+
"superseded_by",
|
|
19027
|
+
"visibility",
|
|
19028
|
+
"published_at",
|
|
19029
|
+
"geohash",
|
|
19030
|
+
"topics",
|
|
19031
|
+
"topics_user_managed",
|
|
19032
|
+
"media",
|
|
19033
|
+
"source"
|
|
19034
|
+
];
|
|
19035
|
+
const embedInBackground = (memory) => {
|
|
19036
|
+
eagerEmbedContent(
|
|
19037
|
+
memory.content,
|
|
19038
|
+
options.embeddingOptions,
|
|
19039
|
+
vaultCache,
|
|
19040
|
+
vaultCtx,
|
|
19041
|
+
memory.uniqueId,
|
|
19042
|
+
memory.updatedAt
|
|
19043
|
+
).catch((err) => {
|
|
19044
|
+
getLogger().warn("[memory/store] Failed to embed memory:", err);
|
|
19045
|
+
});
|
|
19046
|
+
};
|
|
19047
|
+
return {
|
|
19048
|
+
list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
|
|
19049
|
+
get: (id) => getVaultMemoryOp(vaultCtx, id),
|
|
19050
|
+
listArchived: async () => {
|
|
19051
|
+
const ids = await vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), Q8.where("archived_at", Q8.notEq(null)), ...ownedBy).fetchIds();
|
|
19052
|
+
if (ids.length === 0) return [];
|
|
19053
|
+
const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
|
|
19054
|
+
return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
|
|
19055
|
+
},
|
|
19056
|
+
memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
|
|
19057
|
+
topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
|
|
19058
|
+
create: async (input) => {
|
|
19059
|
+
const created = await createVaultMemoryOp(vaultCtx, input);
|
|
19060
|
+
if (input.embedding === void 0) embedInBackground(created);
|
|
19061
|
+
return created;
|
|
19062
|
+
},
|
|
19063
|
+
createMany: async (inputs) => {
|
|
19064
|
+
const created = await createVaultMemoriesBatchOp(vaultCtx, inputs);
|
|
19065
|
+
created.forEach((memory, i) => {
|
|
19066
|
+
if (inputs[i].embedding === void 0) embedInBackground(memory);
|
|
19067
|
+
});
|
|
19068
|
+
return created;
|
|
19069
|
+
},
|
|
19070
|
+
update: async (id, patch) => {
|
|
19071
|
+
const reembed = patch.embedding === void 0;
|
|
19072
|
+
const updated = await updateVaultMemoryOp(
|
|
19073
|
+
vaultCtx,
|
|
19074
|
+
id,
|
|
19075
|
+
reembed ? { ...patch, embedding: null } : patch
|
|
19076
|
+
);
|
|
19077
|
+
if (!updated) return null;
|
|
19078
|
+
vaultCache.delete(id);
|
|
19079
|
+
if (reembed) embedInBackground(updated);
|
|
19080
|
+
return updated;
|
|
19081
|
+
},
|
|
19082
|
+
delete: async (id) => {
|
|
19083
|
+
const deleted = await deleteVaultMemoryOp(vaultCtx, id);
|
|
19084
|
+
if (deleted) vaultCache.delete(id);
|
|
19085
|
+
return deleted;
|
|
19086
|
+
},
|
|
19087
|
+
supersede: (id, supersededById) => supersedeVaultMemoryOp(vaultCtx, id, supersededById),
|
|
19088
|
+
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
19089
|
+
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
19090
|
+
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
19091
|
+
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
19092
|
+
const owned = await vaultCtx.vaultMemoryCollection.query(Q8.where("id", memoryId), Q8.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
19093
|
+
return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
|
|
19094
|
+
}),
|
|
19095
|
+
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
19096
|
+
recall: (query, recallOptions) => recall(
|
|
19097
|
+
query,
|
|
19098
|
+
{ vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions, vaultCache },
|
|
19099
|
+
{ ...recallOptions, types: ["fact"] }
|
|
19100
|
+
),
|
|
19101
|
+
retain: (content, retainOptions) => retain(
|
|
19102
|
+
content,
|
|
19103
|
+
{ vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
|
|
19104
|
+
retainOptions
|
|
19105
|
+
),
|
|
19106
|
+
subscribe: (onChange, subscribeOptions) => {
|
|
19107
|
+
const afterFirst = () => {
|
|
19108
|
+
let first = true;
|
|
19109
|
+
return () => {
|
|
19110
|
+
if (first) first = false;
|
|
19111
|
+
else onChange();
|
|
19112
|
+
};
|
|
19113
|
+
};
|
|
19114
|
+
const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), ...ownedBy).observeWithColumns(
|
|
19115
|
+
subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
|
|
19116
|
+
);
|
|
19117
|
+
const subscriptions = [memories.subscribe(afterFirst())];
|
|
19118
|
+
if (subscribeOptions?.topics) {
|
|
19119
|
+
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
|
|
19120
|
+
subscriptions.push(
|
|
19121
|
+
entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
|
|
19122
|
+
);
|
|
19123
|
+
}
|
|
19124
|
+
return () => subscriptions.forEach((s) => s.unsubscribe());
|
|
19125
|
+
},
|
|
19126
|
+
maintenance: {
|
|
19127
|
+
createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
|
|
19128
|
+
getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
|
|
19129
|
+
extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
|
|
19130
|
+
stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
|
|
19131
|
+
relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
|
|
19132
|
+
backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
|
|
19133
|
+
}
|
|
19134
|
+
};
|
|
19135
|
+
}
|
|
19136
|
+
|
|
18791
19137
|
// src/lib/memory/synthesizeProfile.ts
|
|
18792
19138
|
var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
|
|
18793
19139
|
var DEFAULT_FACET_RECALL_LIMIT = 20;
|
|
@@ -19315,199 +19661,6 @@ function normalizeInterests(values) {
|
|
|
19315
19661
|
return out.length > 0 ? out : void 0;
|
|
19316
19662
|
}
|
|
19317
19663
|
|
|
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
19664
|
// src/lib/memory/verifySupport.ts
|
|
19512
19665
|
var DEFAULT_MODEL5 = "inclusionai/ling-2.6-flash";
|
|
19513
19666
|
var DEFAULT_ATTEMPTS3 = 2;
|
|
@@ -19898,7 +20051,7 @@ async function assembleMemoryContext(options) {
|
|
|
19898
20051
|
}
|
|
19899
20052
|
|
|
19900
20053
|
// src/lib/memory/durableExtraction.ts
|
|
19901
|
-
import { Q as
|
|
20054
|
+
import { Q as Q9 } from "@nozbe/watermelondb";
|
|
19902
20055
|
var MAX_JOBS_PER_PASS = 3;
|
|
19903
20056
|
var MAX_ATTEMPTS = 3;
|
|
19904
20057
|
var MAX_FAILED_SESSIONS = 3;
|
|
@@ -20045,7 +20198,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20045
20198
|
...options.retainCtx,
|
|
20046
20199
|
vaultCtx: {
|
|
20047
20200
|
...vault,
|
|
20048
|
-
canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(
|
|
20201
|
+
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
20202
|
}
|
|
20050
20203
|
},
|
|
20051
20204
|
// The model follows the job's scope, not the mode alive at drain time.
|
|
@@ -20187,7 +20340,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20187
20340
|
let scheduleAfterSuccess = false;
|
|
20188
20341
|
try {
|
|
20189
20342
|
await writes;
|
|
20190
|
-
const pending = await jobs.query(
|
|
20343
|
+
const pending = await jobs.query(Q9.where("owner_key", owner), Q9.where("message_ids", Q9.notEq("[]"))).fetch();
|
|
20191
20344
|
storeFailures = 0;
|
|
20192
20345
|
let processed = 0;
|
|
20193
20346
|
for (const job of pending) {
|
|
@@ -20203,7 +20356,7 @@ function createDurableAutoExtractor(options) {
|
|
|
20203
20356
|
let ids = [];
|
|
20204
20357
|
let loaded = [];
|
|
20205
20358
|
try {
|
|
20206
|
-
const conversations = await storage.conversationsCollection.query(
|
|
20359
|
+
const conversations = await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount();
|
|
20207
20360
|
if (!conversations) {
|
|
20208
20361
|
await database.write(() => job.destroyPermanently());
|
|
20209
20362
|
continue;
|
|
@@ -20320,12 +20473,12 @@ function createDurableAutoExtractor(options) {
|
|
|
20320
20473
|
const scope = currentScope();
|
|
20321
20474
|
writes = writes.then(
|
|
20322
20475
|
() => database.write(async () => {
|
|
20323
|
-
const existing = await jobs.query(
|
|
20476
|
+
const existing = await jobs.query(Q9.where("owner_key", owner), Q9.where("conversation_id", conversationId)).fetch();
|
|
20324
20477
|
const job = existing.find(
|
|
20325
20478
|
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
20326
20479
|
);
|
|
20327
20480
|
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
20328
|
-
const rows = await storage.messagesCollection.query(
|
|
20481
|
+
const rows = await storage.messagesCollection.query(Q9.where("id", Q9.oneOf(ids))).fetch();
|
|
20329
20482
|
const sequences = /* @__PURE__ */ new Map();
|
|
20330
20483
|
for (const row of rows) {
|
|
20331
20484
|
const sequence = Number(row._getRaw("message_id"));
|
|
@@ -25980,7 +26133,7 @@ function useDatabaseManager(walletAddress, manager) {
|
|
|
25980
26133
|
}
|
|
25981
26134
|
|
|
25982
26135
|
// src/lib/db/project/operations.ts
|
|
25983
|
-
import { Q as
|
|
26136
|
+
import { Q as Q10 } from "@nozbe/watermelondb";
|
|
25984
26137
|
|
|
25985
26138
|
// src/lib/db/project/types.ts
|
|
25986
26139
|
function generateProjectId() {
|
|
@@ -26011,15 +26164,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
|
|
|
26011
26164
|
return projectToStored(created);
|
|
26012
26165
|
}
|
|
26013
26166
|
async function getProjectOp(ctx, id) {
|
|
26014
|
-
const results = await ctx.projectsCollection.query(
|
|
26167
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26015
26168
|
return results.length > 0 ? projectToStored(results[0]) : null;
|
|
26016
26169
|
}
|
|
26017
26170
|
async function getProjectsOp(ctx) {
|
|
26018
|
-
const results = await ctx.projectsCollection.query(
|
|
26171
|
+
const results = await ctx.projectsCollection.query(Q10.where("is_deleted", false), Q10.sortBy("created_at", Q10.desc)).fetch();
|
|
26019
26172
|
return results.map(projectToStored);
|
|
26020
26173
|
}
|
|
26021
26174
|
async function updateProjectNameOp(ctx, id, name) {
|
|
26022
|
-
const results = await ctx.projectsCollection.query(
|
|
26175
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26023
26176
|
if (results.length > 0) {
|
|
26024
26177
|
await ctx.database.write(async () => {
|
|
26025
26178
|
await results[0].update((proj) => {
|
|
@@ -26031,7 +26184,7 @@ async function updateProjectNameOp(ctx, id, name) {
|
|
|
26031
26184
|
return false;
|
|
26032
26185
|
}
|
|
26033
26186
|
async function updateProjectOp(ctx, id, opts) {
|
|
26034
|
-
const results = await ctx.projectsCollection.query(
|
|
26187
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26035
26188
|
if (results.length > 0) {
|
|
26036
26189
|
await ctx.database.write(async () => {
|
|
26037
26190
|
await results[0].update((proj) => {
|
|
@@ -26043,7 +26196,7 @@ async function updateProjectOp(ctx, id, opts) {
|
|
|
26043
26196
|
return false;
|
|
26044
26197
|
}
|
|
26045
26198
|
async function deleteProjectOp(ctx, id) {
|
|
26046
|
-
const results = await ctx.projectsCollection.query(
|
|
26199
|
+
const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
|
|
26047
26200
|
if (results.length > 0) {
|
|
26048
26201
|
await ctx.database.write(async () => {
|
|
26049
26202
|
await results[0].update((proj) => {
|
|
@@ -26056,18 +26209,18 @@ async function deleteProjectOp(ctx, id) {
|
|
|
26056
26209
|
}
|
|
26057
26210
|
async function getProjectConversationsOp(ctx, projectId) {
|
|
26058
26211
|
const results = await ctx.conversationsCollection.query(
|
|
26059
|
-
|
|
26060
|
-
|
|
26061
|
-
|
|
26212
|
+
Q10.where("project_id", projectId),
|
|
26213
|
+
Q10.where("is_deleted", false),
|
|
26214
|
+
Q10.sortBy("created_at", Q10.desc)
|
|
26062
26215
|
).fetch();
|
|
26063
26216
|
return results.map(conversationToStoredRaw);
|
|
26064
26217
|
}
|
|
26065
26218
|
async function getProjectConversationCountOp(ctx, projectId) {
|
|
26066
|
-
return await ctx.conversationsCollection.query(
|
|
26219
|
+
return await ctx.conversationsCollection.query(Q10.where("project_id", projectId), Q10.where("is_deleted", false)).fetchCount();
|
|
26067
26220
|
}
|
|
26068
26221
|
|
|
26069
26222
|
// src/react/useFiles.ts
|
|
26070
|
-
import { Q as
|
|
26223
|
+
import { Q as Q11 } from "@nozbe/watermelondb";
|
|
26071
26224
|
import { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState5 } from "react";
|
|
26072
26225
|
function useFiles(options) {
|
|
26073
26226
|
const { database, walletAddress } = options;
|
|
@@ -26085,7 +26238,7 @@ function useFiles(options) {
|
|
|
26085
26238
|
setIsLoading(true);
|
|
26086
26239
|
try {
|
|
26087
26240
|
const coll = database.get("media");
|
|
26088
|
-
await coll.query(
|
|
26241
|
+
await coll.query(Q11.take(1)).fetch();
|
|
26089
26242
|
setMediaCollection(coll);
|
|
26090
26243
|
setIsReady(true);
|
|
26091
26244
|
} catch (error) {
|
|
@@ -26493,7 +26646,7 @@ function useFiles(options) {
|
|
|
26493
26646
|
}
|
|
26494
26647
|
|
|
26495
26648
|
// src/react/useProjects.ts
|
|
26496
|
-
import { Q as
|
|
26649
|
+
import { Q as Q12 } from "@nozbe/watermelondb";
|
|
26497
26650
|
import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo6, useState as useState6 } from "react";
|
|
26498
26651
|
function useProjects(options) {
|
|
26499
26652
|
const { database, initialProjectId } = options;
|
|
@@ -26515,7 +26668,7 @@ function useProjects(options) {
|
|
|
26515
26668
|
conversations: convColl?.table
|
|
26516
26669
|
});
|
|
26517
26670
|
getLogger().debug("[useProjects] Running test query on projects table...");
|
|
26518
|
-
const testResult = await projColl.query(
|
|
26671
|
+
const testResult = await projColl.query(Q12.take(1)).fetch();
|
|
26519
26672
|
getLogger().debug(
|
|
26520
26673
|
"[useProjects] Test query succeeded, found",
|
|
26521
26674
|
testResult.length,
|
|
@@ -26602,7 +26755,7 @@ function useProjects(options) {
|
|
|
26602
26755
|
if (!projectsCollection) {
|
|
26603
26756
|
return;
|
|
26604
26757
|
}
|
|
26605
|
-
const subscription = projectsCollection.query(
|
|
26758
|
+
const subscription = projectsCollection.query(Q12.where("is_deleted", false)).observe().subscribe((records) => {
|
|
26606
26759
|
setProjects(records.map(projectToStored));
|
|
26607
26760
|
});
|
|
26608
26761
|
return () => subscription.unsubscribe();
|
|
@@ -26725,7 +26878,7 @@ function useProjects(options) {
|
|
|
26725
26878
|
}
|
|
26726
26879
|
|
|
26727
26880
|
// src/lib/db/settings/operations.ts
|
|
26728
|
-
import { Q as
|
|
26881
|
+
import { Q as Q13 } from "@nozbe/watermelondb";
|
|
26729
26882
|
function modelPreferenceToStored(preference) {
|
|
26730
26883
|
return {
|
|
26731
26884
|
uniqueId: preference.id,
|
|
@@ -26734,12 +26887,12 @@ function modelPreferenceToStored(preference) {
|
|
|
26734
26887
|
};
|
|
26735
26888
|
}
|
|
26736
26889
|
async function getModelPreferenceOp(ctx, walletAddress) {
|
|
26737
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26890
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26738
26891
|
return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
|
|
26739
26892
|
}
|
|
26740
26893
|
async function setModelPreferenceOp(ctx, walletAddress, models) {
|
|
26741
26894
|
const result = await ctx.database.write(async () => {
|
|
26742
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26895
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26743
26896
|
if (results.length > 0) {
|
|
26744
26897
|
const preference = results[0];
|
|
26745
26898
|
await preference.update((pref) => {
|
|
@@ -26757,7 +26910,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
|
|
|
26757
26910
|
return modelPreferenceToStored(result);
|
|
26758
26911
|
}
|
|
26759
26912
|
async function deleteModelPreferenceOp(ctx, walletAddress) {
|
|
26760
|
-
const results = await ctx.modelPreferencesCollection.query(
|
|
26913
|
+
const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
|
|
26761
26914
|
if (results.length === 0) return false;
|
|
26762
26915
|
await ctx.database.write(async () => {
|
|
26763
26916
|
await results[0].destroyPermanently();
|
|
@@ -26781,7 +26934,7 @@ var settingsStorageSchema = appSchema3({
|
|
|
26781
26934
|
});
|
|
26782
26935
|
|
|
26783
26936
|
// src/lib/db/vaultFolders/operations.ts
|
|
26784
|
-
import { Q as
|
|
26937
|
+
import { Q as Q14 } from "@nozbe/watermelondb";
|
|
26785
26938
|
function folderToStored(folder) {
|
|
26786
26939
|
return {
|
|
26787
26940
|
uniqueId: folder.id,
|
|
@@ -26806,7 +26959,7 @@ async function createVaultFolderOp(ctx, opts) {
|
|
|
26806
26959
|
return folderToStored(created);
|
|
26807
26960
|
}
|
|
26808
26961
|
async function getAllVaultFoldersOp(ctx) {
|
|
26809
|
-
const results = await ctx.vaultFolderCollection.query(
|
|
26962
|
+
const results = await ctx.vaultFolderCollection.query(Q14.where("is_deleted", false), Q14.sortBy("created_at", Q14.desc)).fetch();
|
|
26810
26963
|
return results.map(folderToStored);
|
|
26811
26964
|
}
|
|
26812
26965
|
async function updateVaultFolderOp(ctx, id, opts) {
|
|
@@ -26815,7 +26968,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
|
|
|
26815
26968
|
if (record.isDeleted) return null;
|
|
26816
26969
|
const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
|
|
26817
26970
|
const updated = await ctx.database.write(async () => {
|
|
26818
|
-
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(
|
|
26971
|
+
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch() : [];
|
|
26819
26972
|
const updates = [];
|
|
26820
26973
|
updates.push(
|
|
26821
26974
|
record.prepareUpdate((r) => {
|
|
@@ -26843,7 +26996,7 @@ async function deleteVaultFolderOp(ctx, id) {
|
|
|
26843
26996
|
const record = await ctx.vaultFolderCollection.find(id);
|
|
26844
26997
|
if (record.isDeleted) return false;
|
|
26845
26998
|
await ctx.database.write(async () => {
|
|
26846
|
-
const memories = await ctx.vaultMemoryCollection.query(
|
|
26999
|
+
const memories = await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch();
|
|
26847
27000
|
const preparedMemories = memories.map(
|
|
26848
27001
|
(memory) => memory.prepareUpdate((r) => {
|
|
26849
27002
|
r._setRaw("folder_id", null);
|
|
@@ -26912,7 +27065,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
|
|
|
26912
27065
|
}
|
|
26913
27066
|
}
|
|
26914
27067
|
async function getVaultFolderMemoryCountOp(ctx, folderId) {
|
|
26915
|
-
return await ctx.vaultMemoryCollection.query(
|
|
27068
|
+
return await ctx.vaultMemoryCollection.query(Q14.where("folder_id", folderId), Q14.where("is_deleted", false)).fetchCount();
|
|
26916
27069
|
}
|
|
26917
27070
|
|
|
26918
27071
|
// src/lib/db/vaultFolders/defaults.ts
|
|
@@ -26958,7 +27111,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
|
|
|
26958
27111
|
import { useCallback as useCallback7, useMemo as useMemo7, useSyncExternalStore } from "react";
|
|
26959
27112
|
|
|
26960
27113
|
// src/lib/db/userPreferences/operations.ts
|
|
26961
|
-
import { Q as
|
|
27114
|
+
import { Q as Q15 } from "@nozbe/watermelondb";
|
|
26962
27115
|
function userPreferenceToStored(preference) {
|
|
26963
27116
|
return {
|
|
26964
27117
|
uniqueId: preference.id,
|
|
@@ -26973,7 +27126,7 @@ function userPreferenceToStored(preference) {
|
|
|
26973
27126
|
};
|
|
26974
27127
|
}
|
|
26975
27128
|
async function getUserPreferenceOp(ctx, walletAddress) {
|
|
26976
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27129
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
26977
27130
|
return results.length > 0 ? userPreferenceToStored(results[0]) : null;
|
|
26978
27131
|
}
|
|
26979
27132
|
async function createUserPreferenceOp(ctx, opts) {
|
|
@@ -26993,7 +27146,7 @@ async function createUserPreferenceOp(ctx, opts) {
|
|
|
26993
27146
|
return userPreferenceToStored(created);
|
|
26994
27147
|
}
|
|
26995
27148
|
async function updateUserPreferenceOp(ctx, walletAddress, opts) {
|
|
26996
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27149
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
26997
27150
|
if (results.length === 0) return null;
|
|
26998
27151
|
const preference = results[0];
|
|
26999
27152
|
await ctx.database.write(async () => {
|
|
@@ -27021,7 +27174,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
|
|
|
27021
27174
|
async function setUserPreferenceOp(ctx, walletAddress, opts) {
|
|
27022
27175
|
const now = Date.now();
|
|
27023
27176
|
const result = await ctx.database.write(async () => {
|
|
27024
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27177
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27025
27178
|
if (results.length > 0) {
|
|
27026
27179
|
const preference = results[0];
|
|
27027
27180
|
await preference.update((pref) => {
|
|
@@ -27069,7 +27222,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
|
|
|
27069
27222
|
return updateUserPreferenceOp(ctx, walletAddress, { models });
|
|
27070
27223
|
}
|
|
27071
27224
|
async function deleteUserPreferenceOp(ctx, walletAddress) {
|
|
27072
|
-
const results = await ctx.userPreferencesCollection.query(
|
|
27225
|
+
const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27073
27226
|
if (results.length === 0) return false;
|
|
27074
27227
|
await ctx.database.write(async () => {
|
|
27075
27228
|
await results[0].destroyPermanently();
|
|
@@ -27084,9 +27237,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
|
|
|
27084
27237
|
if (existing) {
|
|
27085
27238
|
return existing;
|
|
27086
27239
|
}
|
|
27087
|
-
const modelResults = await ctx.modelPreferencesCollection.query(
|
|
27240
|
+
const modelResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
|
|
27088
27241
|
const personalityKey = `${walletAddress}_personality_settings`;
|
|
27089
|
-
const personalityResults = await ctx.modelPreferencesCollection.query(
|
|
27242
|
+
const personalityResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", personalityKey)).fetch();
|
|
27090
27243
|
if (modelResults.length === 0 && personalityResults.length === 0) {
|
|
27091
27244
|
return null;
|
|
27092
27245
|
}
|
|
@@ -27192,7 +27345,7 @@ var SLIDER_CONFIG = [
|
|
|
27192
27345
|
];
|
|
27193
27346
|
|
|
27194
27347
|
// src/react/userSettingsStore.ts
|
|
27195
|
-
import { Q as
|
|
27348
|
+
import { Q as Q16 } from "@nozbe/watermelondb";
|
|
27196
27349
|
var EMPTY_SNAPSHOT = Object.freeze({
|
|
27197
27350
|
modelPreference: null,
|
|
27198
27351
|
userPreference: null,
|
|
@@ -27254,7 +27407,7 @@ async function startLoad(entry, walletAddress) {
|
|
|
27254
27407
|
}
|
|
27255
27408
|
function startObserve(entry, walletAddress) {
|
|
27256
27409
|
let isInitialEmission = true;
|
|
27257
|
-
entry.observeSub = entry.storageCtx.userPreferencesCollection.query(
|
|
27410
|
+
entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q16.where("wallet_address", walletAddress)).observeWithColumns([
|
|
27258
27411
|
"nickname",
|
|
27259
27412
|
"occupation",
|
|
27260
27413
|
"description",
|
|
@@ -27518,7 +27671,7 @@ function useSettings(options) {
|
|
|
27518
27671
|
}
|
|
27519
27672
|
|
|
27520
27673
|
// src/lib/db/appFiles/operations.ts
|
|
27521
|
-
import { Q as
|
|
27674
|
+
import { Q as Q17 } from "@nozbe/watermelondb";
|
|
27522
27675
|
|
|
27523
27676
|
// src/utils/paths.ts
|
|
27524
27677
|
function normalizePath(p) {
|
|
@@ -27544,7 +27697,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
|
|
|
27544
27697
|
const normalized = normalizePath(path);
|
|
27545
27698
|
const now = Date.now();
|
|
27546
27699
|
const result = await ctx.database.write(async () => {
|
|
27547
|
-
const existing = await ctx.appFilesCollection.query(
|
|
27700
|
+
const existing = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27548
27701
|
if (existing.length > 0) {
|
|
27549
27702
|
await existing[0].update((f) => {
|
|
27550
27703
|
f._setRaw("content", content);
|
|
@@ -27564,11 +27717,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
|
|
|
27564
27717
|
}
|
|
27565
27718
|
async function getAppFileOp(ctx, conversationId, path) {
|
|
27566
27719
|
const normalized = normalizePath(path);
|
|
27567
|
-
const results = await ctx.appFilesCollection.query(
|
|
27720
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27568
27721
|
return results.length > 0 ? appFileToStored(results[0]) : null;
|
|
27569
27722
|
}
|
|
27570
27723
|
async function getAppFilesOp(ctx, conversationId) {
|
|
27571
|
-
const results = await ctx.appFilesCollection.query(
|
|
27724
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
|
|
27572
27725
|
return results.map(appFileToStored);
|
|
27573
27726
|
}
|
|
27574
27727
|
async function getAppFileMapOp(ctx, conversationId) {
|
|
@@ -27579,7 +27732,7 @@ async function getAppFileMapOp(ctx, conversationId) {
|
|
|
27579
27732
|
}
|
|
27580
27733
|
async function deleteAppFileOp(ctx, conversationId, path) {
|
|
27581
27734
|
const normalized = normalizePath(path);
|
|
27582
|
-
const results = await ctx.appFilesCollection.query(
|
|
27735
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
|
|
27583
27736
|
if (results.length === 0) return false;
|
|
27584
27737
|
await ctx.database.write(async () => {
|
|
27585
27738
|
await results[0].destroyPermanently();
|
|
@@ -27587,7 +27740,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
|
|
|
27587
27740
|
return true;
|
|
27588
27741
|
}
|
|
27589
27742
|
async function deleteAllAppFilesOp(ctx, conversationId) {
|
|
27590
|
-
const results = await ctx.appFilesCollection.query(
|
|
27743
|
+
const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
|
|
27591
27744
|
if (results.length === 0) return;
|
|
27592
27745
|
await ctx.database.write(async () => {
|
|
27593
27746
|
const batch = results.map((file) => file.prepareDestroyPermanently());
|
|
@@ -27596,7 +27749,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
|
|
|
27596
27749
|
}
|
|
27597
27750
|
|
|
27598
27751
|
// src/lib/db/conversationMemory/operations.ts
|
|
27599
|
-
import { Q as
|
|
27752
|
+
import { Q as Q18 } from "@nozbe/watermelondb";
|
|
27600
27753
|
var MAX_PER_CONVERSATION = 200;
|
|
27601
27754
|
function conversationMemoryToStored(row) {
|
|
27602
27755
|
return {
|
|
@@ -27611,7 +27764,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
27611
27764
|
if (!conversationId || items.length === 0) return;
|
|
27612
27765
|
const now = Date.now();
|
|
27613
27766
|
await ctx.database.write(async () => {
|
|
27614
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
27767
|
+
const existing = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
|
|
27615
27768
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
27616
27769
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
27617
27770
|
const deduped = [];
|
|
@@ -27646,20 +27799,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
27646
27799
|
}
|
|
27647
27800
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
27648
27801
|
if (!conversationId) return [];
|
|
27649
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
27802
|
+
const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
|
|
27650
27803
|
return rows.map(conversationMemoryToStored);
|
|
27651
27804
|
}
|
|
27652
27805
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
27653
27806
|
if (!conversationId) return;
|
|
27654
27807
|
await ctx.database.write(async () => {
|
|
27655
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
27808
|
+
const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId)).fetch();
|
|
27656
27809
|
if (rows.length === 0) return;
|
|
27657
27810
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
27658
27811
|
});
|
|
27659
27812
|
}
|
|
27660
27813
|
|
|
27661
27814
|
// src/lib/db/savedTools/operations.ts
|
|
27662
|
-
import { Q as
|
|
27815
|
+
import { Q as Q19 } from "@nozbe/watermelondb";
|
|
27663
27816
|
function savedToolToStored(tool) {
|
|
27664
27817
|
return {
|
|
27665
27818
|
uniqueId: tool.id,
|
|
@@ -27692,7 +27845,7 @@ async function createSavedToolOp(ctx, opts) {
|
|
|
27692
27845
|
return savedToolToStored(created);
|
|
27693
27846
|
}
|
|
27694
27847
|
async function getAllSavedToolsOp(ctx) {
|
|
27695
|
-
const results = await ctx.savedToolsCollection.query(
|
|
27848
|
+
const results = await ctx.savedToolsCollection.query(Q19.where("is_deleted", false), Q19.sortBy("created_at", Q19.desc)).fetch();
|
|
27696
27849
|
return results.map(savedToolToStored);
|
|
27697
27850
|
}
|
|
27698
27851
|
async function getSavedToolByIdOp(ctx, uniqueId) {
|
|
@@ -30348,8 +30501,8 @@ function createDropboxFileIndex(backupFolder) {
|
|
|
30348
30501
|
};
|
|
30349
30502
|
}
|
|
30350
30503
|
async function readLocalUpdatedAt(database, conversationId) {
|
|
30351
|
-
const { Q:
|
|
30352
|
-
const records = await database.get("conversations").query(
|
|
30504
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
30505
|
+
const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
|
|
30353
30506
|
const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
|
|
30354
30507
|
return match ? match.updatedAt : null;
|
|
30355
30508
|
}
|
|
@@ -30405,9 +30558,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
|
|
|
30405
30558
|
}
|
|
30406
30559
|
async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
|
|
30407
30560
|
await deps.requestEncryptionKey(userAddress);
|
|
30408
|
-
const { Q:
|
|
30561
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
30409
30562
|
const conversationsCollection = database.get("conversations");
|
|
30410
|
-
const records = await conversationsCollection.query(
|
|
30563
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
30411
30564
|
const conversations = records.map(conversationToStoredRaw);
|
|
30412
30565
|
const total = conversations.length;
|
|
30413
30566
|
if (total === 0) {
|
|
@@ -31089,8 +31242,8 @@ function createDriveFileIndex(folderId) {
|
|
|
31089
31242
|
};
|
|
31090
31243
|
}
|
|
31091
31244
|
async function readLocalUpdatedAt2(database, conversationId) {
|
|
31092
|
-
const { Q:
|
|
31093
|
-
const records = await database.get("conversations").query(
|
|
31245
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31246
|
+
const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
|
|
31094
31247
|
const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
|
|
31095
31248
|
return match ? match.updatedAt : null;
|
|
31096
31249
|
}
|
|
@@ -31170,9 +31323,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
|
|
|
31170
31323
|
}
|
|
31171
31324
|
const { folderId, token: activeToken } = folderResult;
|
|
31172
31325
|
const fileIndex = createDriveFileIndex(folderId);
|
|
31173
|
-
const { Q:
|
|
31326
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31174
31327
|
const conversationsCollection = database.get("conversations");
|
|
31175
|
-
const records = await conversationsCollection.query(
|
|
31328
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
31176
31329
|
const conversations = records.map(conversationToStoredRaw);
|
|
31177
31330
|
const total = conversations.length;
|
|
31178
31331
|
if (total === 0) {
|
|
@@ -31757,9 +31910,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
|
|
|
31757
31910
|
const filename = `${conversationId}.json`;
|
|
31758
31911
|
const existingFile = await findICloudFile(filename);
|
|
31759
31912
|
if (existingFile) {
|
|
31760
|
-
const { Q:
|
|
31913
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31761
31914
|
const conversationsCollection = database.get("conversations");
|
|
31762
|
-
const records = await conversationsCollection.query(
|
|
31915
|
+
const records = await conversationsCollection.query(Q20.where("conversation_id", conversationId)).fetch();
|
|
31763
31916
|
if (records.length > 0) {
|
|
31764
31917
|
const conversation = conversationToStoredRaw(records[0]);
|
|
31765
31918
|
const localUpdated = conversation.updatedAt.getTime();
|
|
@@ -31789,9 +31942,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
|
|
|
31789
31942
|
}
|
|
31790
31943
|
async function performICloudExport(database, userAddress, deps, onProgress) {
|
|
31791
31944
|
await deps.requestEncryptionKey(userAddress);
|
|
31792
|
-
const { Q:
|
|
31945
|
+
const { Q: Q20 } = await import("@nozbe/watermelondb");
|
|
31793
31946
|
const conversationsCollection = database.get("conversations");
|
|
31794
|
-
const records = await conversationsCollection.query(
|
|
31947
|
+
const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
|
|
31795
31948
|
const conversations = records.map(conversationToStoredRaw);
|
|
31796
31949
|
const total = conversations.length;
|
|
31797
31950
|
if (total === 0) {
|
|
@@ -35766,6 +35919,7 @@ export {
|
|
|
35766
35919
|
createGitHubTools,
|
|
35767
35920
|
createLlmDecayClassifier,
|
|
35768
35921
|
createLlmNeighborRefiner,
|
|
35922
|
+
createLocalMemoryStore,
|
|
35769
35923
|
createMediaBatchOp,
|
|
35770
35924
|
createMediaOp,
|
|
35771
35925
|
createMemoryEngineTool,
|