@anuma/sdk 3.8.3 → 3.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/{chunk-IFZZQPRO.mjs → chunk-42Y42CAZ.mjs} +60 -40
- package/dist/expo/index.cjs +228 -46
- package/dist/expo/index.d.mts +7 -1
- package/dist/expo/index.d.ts +7 -1
- package/dist/expo/index.mjs +170 -8
- package/dist/expo/{recall-MUFOZB6P.mjs → recall-JFZ3Z6EX.mjs} +1 -1
- package/dist/react/{chunk-35BHTCK4.mjs → chunk-NLVSQAYH.mjs} +60 -40
- package/dist/react/index.cjs +228 -46
- package/dist/react/index.d.mts +15 -4
- package/dist/react/index.d.ts +15 -4
- package/dist/react/index.mjs +170 -8
- package/dist/react/{recall-JUERXQA7.mjs → recall-BCEH7U2Z.mjs} +1 -1
- package/dist/server/{chunk-GKN5NJKZ.mjs → chunk-FS56IDOW.mjs} +60 -40
- package/dist/server/index.cjs +228 -46
- package/dist/server/index.d.mts +7 -1
- package/dist/server/index.d.ts +7 -1
- package/dist/server/index.mjs +170 -8
- package/dist/server/{recall-XZ6WLFPJ.mjs → recall-VDMDNQNB.mjs} +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
updateVaultMemoryOp,
|
|
150
150
|
useEncryption,
|
|
151
151
|
vaultMemoryToStored
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-NLVSQAYH.mjs";
|
|
153
153
|
import {
|
|
154
154
|
PiiRedactor,
|
|
155
155
|
createStreamingDeAnonymizer,
|
|
@@ -6743,6 +6743,162 @@ __decorateClass([
|
|
|
6743
6743
|
// src/lib/memory/autoExtract.ts
|
|
6744
6744
|
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
6745
6745
|
|
|
6746
|
+
// src/lib/memory/entitySalience.ts
|
|
6747
|
+
var GENERIC_ENTITY_NAMES = /* @__PURE__ */ new Set([
|
|
6748
|
+
// Relative and absolute time
|
|
6749
|
+
"today",
|
|
6750
|
+
"tomorrow",
|
|
6751
|
+
"yesterday",
|
|
6752
|
+
"tonight",
|
|
6753
|
+
"morning",
|
|
6754
|
+
"afternoon",
|
|
6755
|
+
"evening",
|
|
6756
|
+
"night",
|
|
6757
|
+
"day",
|
|
6758
|
+
"date",
|
|
6759
|
+
"time",
|
|
6760
|
+
"week",
|
|
6761
|
+
"weekend",
|
|
6762
|
+
"weekday",
|
|
6763
|
+
"month",
|
|
6764
|
+
"year",
|
|
6765
|
+
"monday",
|
|
6766
|
+
"tuesday",
|
|
6767
|
+
"wednesday",
|
|
6768
|
+
"thursday",
|
|
6769
|
+
"friday",
|
|
6770
|
+
"saturday",
|
|
6771
|
+
"sunday",
|
|
6772
|
+
"january",
|
|
6773
|
+
"february",
|
|
6774
|
+
"march",
|
|
6775
|
+
"april",
|
|
6776
|
+
"may",
|
|
6777
|
+
"june",
|
|
6778
|
+
"july",
|
|
6779
|
+
"august",
|
|
6780
|
+
"september",
|
|
6781
|
+
"october",
|
|
6782
|
+
"november",
|
|
6783
|
+
"december",
|
|
6784
|
+
// Generic containers and venues — the named ones ("Blue Bottle on Valencia",
|
|
6785
|
+
// "Stanford") are unaffected because they are not bare tokens.
|
|
6786
|
+
"home",
|
|
6787
|
+
"house",
|
|
6788
|
+
"apartment",
|
|
6789
|
+
"room",
|
|
6790
|
+
"office",
|
|
6791
|
+
"work",
|
|
6792
|
+
"workplace",
|
|
6793
|
+
"school",
|
|
6794
|
+
"gym",
|
|
6795
|
+
"store",
|
|
6796
|
+
"shop",
|
|
6797
|
+
"hospital",
|
|
6798
|
+
"airport",
|
|
6799
|
+
"hotel",
|
|
6800
|
+
"city",
|
|
6801
|
+
"town",
|
|
6802
|
+
"country",
|
|
6803
|
+
"place",
|
|
6804
|
+
// Generic calendar entries — "Chicago Marathon" survives, "meeting" doesn't.
|
|
6805
|
+
"meeting",
|
|
6806
|
+
"call",
|
|
6807
|
+
"appointment",
|
|
6808
|
+
"reminder",
|
|
6809
|
+
"event",
|
|
6810
|
+
"birthday",
|
|
6811
|
+
"breakfast",
|
|
6812
|
+
"lunch",
|
|
6813
|
+
"dinner",
|
|
6814
|
+
"brunch",
|
|
6815
|
+
"vacation",
|
|
6816
|
+
"holiday",
|
|
6817
|
+
"trip",
|
|
6818
|
+
// Plurals are listed explicitly rather than stemmed: naive `s`-stripping
|
|
6819
|
+
// would fold real titles into generics ("The Times" → "time"). Only plurals
|
|
6820
|
+
// that are junk as topics in their own right belong here — note the absence
|
|
6821
|
+
// of "times", "places", and anything else that reads as a name.
|
|
6822
|
+
"days",
|
|
6823
|
+
"weeks",
|
|
6824
|
+
"weekends",
|
|
6825
|
+
"months",
|
|
6826
|
+
"years",
|
|
6827
|
+
"rooms",
|
|
6828
|
+
"offices",
|
|
6829
|
+
"houses",
|
|
6830
|
+
"apartments",
|
|
6831
|
+
"stores",
|
|
6832
|
+
"shops",
|
|
6833
|
+
"hotels",
|
|
6834
|
+
"meetings",
|
|
6835
|
+
"calls",
|
|
6836
|
+
"appointments",
|
|
6837
|
+
"reminders",
|
|
6838
|
+
"events",
|
|
6839
|
+
"birthdays",
|
|
6840
|
+
"trips",
|
|
6841
|
+
"vacations",
|
|
6842
|
+
"holidays",
|
|
6843
|
+
// Meta / filler the models occasionally echo back as an entity
|
|
6844
|
+
"user",
|
|
6845
|
+
"assistant",
|
|
6846
|
+
"memory",
|
|
6847
|
+
"memories",
|
|
6848
|
+
"note",
|
|
6849
|
+
"notes",
|
|
6850
|
+
"thing",
|
|
6851
|
+
"things",
|
|
6852
|
+
"stuff",
|
|
6853
|
+
"something",
|
|
6854
|
+
"someone",
|
|
6855
|
+
"anything",
|
|
6856
|
+
"everything",
|
|
6857
|
+
"none",
|
|
6858
|
+
"other",
|
|
6859
|
+
"misc",
|
|
6860
|
+
"general",
|
|
6861
|
+
"unknown"
|
|
6862
|
+
]);
|
|
6863
|
+
function isGenericEntityName(name) {
|
|
6864
|
+
const tokens = name.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((token) => token.length > 0);
|
|
6865
|
+
if (tokens.length === 0) return true;
|
|
6866
|
+
const distinctive = tokens.filter(
|
|
6867
|
+
(token) => !GENERIC_ENTITY_NAMES.has(token) && !ARTICLES.has(token) && !WEAK_MODIFIERS.has(token)
|
|
6868
|
+
);
|
|
6869
|
+
if (distinctive.length > 0) return false;
|
|
6870
|
+
const generic = tokens.filter((token) => GENERIC_ENTITY_NAMES.has(token));
|
|
6871
|
+
if (generic.length === 0) return true;
|
|
6872
|
+
const titleShaped = generic.length === 1 && tokens.some((token) => ARTICLES.has(token)) && !tokens.some((token) => WEAK_MODIFIERS.has(token));
|
|
6873
|
+
return !titleShaped;
|
|
6874
|
+
}
|
|
6875
|
+
var ARTICLES = /* @__PURE__ */ new Set(["the", "a", "an"]);
|
|
6876
|
+
var WEAK_MODIFIERS = /* @__PURE__ */ new Set([
|
|
6877
|
+
"my",
|
|
6878
|
+
"our",
|
|
6879
|
+
"their",
|
|
6880
|
+
"his",
|
|
6881
|
+
"her",
|
|
6882
|
+
"its",
|
|
6883
|
+
"this",
|
|
6884
|
+
"that",
|
|
6885
|
+
"next",
|
|
6886
|
+
"last",
|
|
6887
|
+
"upcoming",
|
|
6888
|
+
"every",
|
|
6889
|
+
"at",
|
|
6890
|
+
"in",
|
|
6891
|
+
"on",
|
|
6892
|
+
"of",
|
|
6893
|
+
"for",
|
|
6894
|
+
"with",
|
|
6895
|
+
"from",
|
|
6896
|
+
"to",
|
|
6897
|
+
"by",
|
|
6898
|
+
"and",
|
|
6899
|
+
"or"
|
|
6900
|
+
]);
|
|
6901
|
+
|
|
6746
6902
|
// src/lib/memory/injectionClassifier.ts
|
|
6747
6903
|
var DEFAULT_MODEL = "inclusionai/ling-2.6-flash";
|
|
6748
6904
|
var DEFAULT_ATTEMPTS = 2;
|
|
@@ -7671,13 +7827,13 @@ function parseEntities(raw) {
|
|
|
7671
7827
|
for (const e of raw) {
|
|
7672
7828
|
if (typeof e === "string") {
|
|
7673
7829
|
const name2 = e.trim();
|
|
7674
|
-
if (name2.length > 0) out.push({ name: name2 });
|
|
7830
|
+
if (name2.length > 0 && !isGenericEntityName(name2)) out.push({ name: name2 });
|
|
7675
7831
|
continue;
|
|
7676
7832
|
}
|
|
7677
7833
|
if (typeof e !== "object" || e === null) continue;
|
|
7678
7834
|
const obj = e;
|
|
7679
7835
|
const name = typeof obj.name === "string" ? obj.name.trim() : "";
|
|
7680
|
-
if (name.length === 0) continue;
|
|
7836
|
+
if (name.length === 0 || isGenericEntityName(name)) continue;
|
|
7681
7837
|
const kind = typeof obj.kind === "string" && ENTITY_KINDS.includes(obj.kind) ? obj.kind : void 0;
|
|
7682
7838
|
out.push(kind !== void 0 ? { name, kind } : { name });
|
|
7683
7839
|
}
|
|
@@ -7897,9 +8053,11 @@ function createAutoExtractor(options) {
|
|
|
7897
8053
|
}
|
|
7898
8054
|
}
|
|
7899
8055
|
);
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
8056
|
+
if (outcome !== "empty-after-retry") {
|
|
8057
|
+
const advancedTo = window2[window2.length - 1].id;
|
|
8058
|
+
stateFor(conversationId).watermark = advancedTo;
|
|
8059
|
+
persistCursor(conversationId, messages, advancedTo, contiguous);
|
|
8060
|
+
}
|
|
7903
8061
|
for (let i = 0; i < results.length; i++) {
|
|
7904
8062
|
if (results[i].action === "suppressed") continue;
|
|
7905
8063
|
options.onMemoryExtracted?.({
|
|
@@ -8980,7 +9138,11 @@ var SYSTEM_PROMPT4 = `You assign topics to saved memories for a personal memory
|
|
|
8980
9138
|
|
|
8981
9139
|
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.
|
|
8982
9140
|
|
|
8983
|
-
Include only NAMED entities, skip generic/common nouns.
|
|
9141
|
+
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:
|
|
9142
|
+
- 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.
|
|
9143
|
+
- KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
|
|
9144
|
+
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
9145
|
+
${ENTITY_KIND_GUIDELINES}
|
|
8984
9146
|
|
|
8985
9147
|
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
|
|
8986
9148
|
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
@@ -8992,7 +9154,7 @@ async function extractEntitiesForMemories(memories, options) {
|
|
|
8992
9154
|
const redactor = resolvePiiRedactor(options.piiRedaction);
|
|
8993
9155
|
const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
|
|
8994
9156
|
const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
|
|
8995
|
-
When a memory refers to one of these, reuse the EXACT existing name (same spelling and
|
|
9157
|
+
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".
|
|
8996
9158
|
|
|
8997
9159
|
` : "";
|
|
8998
9160
|
for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
|
|
@@ -16003,7 +16003,7 @@ function entityToStored(e) {
|
|
|
16003
16003
|
updatedAt: e.updatedAt
|
|
16004
16004
|
};
|
|
16005
16005
|
}
|
|
16006
|
-
async function
|
|
16006
|
+
async function upsertEntitiesInWrite(ctx, entities) {
|
|
16007
16007
|
const kindByName = /* @__PURE__ */ new Map();
|
|
16008
16008
|
for (const e of entities) {
|
|
16009
16009
|
const name = normalizeEntityName(e.name);
|
|
@@ -16017,60 +16017,62 @@ async function upsertEntitiesOp(ctx, entities) {
|
|
|
16017
16017
|
}
|
|
16018
16018
|
const unique = Array.from(kindByName.keys());
|
|
16019
16019
|
const out = /* @__PURE__ */ new Map();
|
|
16020
|
-
if (unique.length === 0) return out;
|
|
16021
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
const
|
|
16025
|
-
|
|
16026
|
-
return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
|
|
16027
|
-
});
|
|
16028
|
-
const missing = unique.filter((n) => !existingNames.has(n));
|
|
16029
|
-
const created = missing.map(
|
|
16030
|
-
(name) => ctx.entityCollection.prepareCreate((record) => {
|
|
16031
|
-
record._setRaw("canonical_name", name);
|
|
16032
|
-
const kind = kindByName.get(name);
|
|
16033
|
-
if (kind !== void 0) record._setRaw("kind", kind);
|
|
16034
|
-
})
|
|
16035
|
-
);
|
|
16036
|
-
const updated = updates.map(
|
|
16037
|
-
(e) => e.prepareUpdate((record) => {
|
|
16038
|
-
record._setRaw("kind", kindByName.get(e.canonicalName));
|
|
16039
|
-
})
|
|
16040
|
-
);
|
|
16041
|
-
if (created.length > 0 || updated.length > 0) {
|
|
16042
|
-
await ctx.database.batch(...created, ...updated);
|
|
16043
|
-
}
|
|
16044
|
-
for (const e of existing) out.set(e.canonicalName, entityToStored(e));
|
|
16045
|
-
for (const record of created) out.set(record.canonicalName, entityToStored(record));
|
|
16046
|
-
return out;
|
|
16020
|
+
if (unique.length === 0) return { entities: out, operations: [] };
|
|
16021
|
+
const existing = await ctx.entityCollection.query(import_watermelondb2.Q.where("canonical_name", import_watermelondb2.Q.oneOf(unique))).fetch();
|
|
16022
|
+
const existingNames = new Set(existing.map((e) => e.canonicalName));
|
|
16023
|
+
const updates = existing.filter((e) => {
|
|
16024
|
+
const incoming = kindByName.get(e.canonicalName);
|
|
16025
|
+
return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
|
|
16047
16026
|
});
|
|
16027
|
+
const missing = unique.filter((n) => !existingNames.has(n));
|
|
16028
|
+
const created = missing.map(
|
|
16029
|
+
(name) => ctx.entityCollection.prepareCreate((record) => {
|
|
16030
|
+
record._setRaw("canonical_name", name);
|
|
16031
|
+
const kind = kindByName.get(name);
|
|
16032
|
+
if (kind !== void 0) record._setRaw("kind", kind);
|
|
16033
|
+
})
|
|
16034
|
+
);
|
|
16035
|
+
const updated = updates.map(
|
|
16036
|
+
(e) => e.prepareUpdate((record) => {
|
|
16037
|
+
record._setRaw("kind", kindByName.get(e.canonicalName));
|
|
16038
|
+
})
|
|
16039
|
+
);
|
|
16040
|
+
for (const e of existing) out.set(e.canonicalName, entityToStored(e));
|
|
16041
|
+
for (const record of created) out.set(record.canonicalName, entityToStored(record));
|
|
16042
|
+
return { entities: out, operations: [...created, ...updated] };
|
|
16048
16043
|
}
|
|
16049
16044
|
async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
16050
16045
|
if (entityInputs.length === 0) return [];
|
|
16051
16046
|
const normalized = entityInputs.map((e) => typeof e === "string" ? { name: e } : e);
|
|
16052
|
-
const byName = await upsertEntitiesOp(ctx, normalized);
|
|
16053
|
-
const entities = Array.from(byName.values());
|
|
16054
|
-
if (entities.length === 0) return [];
|
|
16055
16047
|
const userId = ctx.userId;
|
|
16056
16048
|
let skipped = false;
|
|
16049
|
+
let entities = [];
|
|
16057
16050
|
await ctx.database.write(async () => {
|
|
16051
|
+
const { entities: byName, operations: entityOps } = await upsertEntitiesInWrite(
|
|
16052
|
+
ctx,
|
|
16053
|
+
normalized
|
|
16054
|
+
);
|
|
16055
|
+
entities = Array.from(byName.values());
|
|
16058
16056
|
if (options?.unlessTopicsUserManaged && await autoLinkBlocked(ctx, memoryId)) {
|
|
16057
|
+
if (entityOps.length > 0) {
|
|
16058
|
+
await ctx.database.batch(...entityOps);
|
|
16059
|
+
}
|
|
16059
16060
|
skipped = true;
|
|
16060
16061
|
return;
|
|
16061
16062
|
}
|
|
16063
|
+
if (entities.length === 0) return;
|
|
16062
16064
|
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb2.Q.where("memory_id", memoryId)).fetch();
|
|
16063
16065
|
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
16064
16066
|
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
16065
|
-
if (toCreate.length === 0) return;
|
|
16066
|
-
const
|
|
16067
|
+
if (entityOps.length === 0 && toCreate.length === 0) return;
|
|
16068
|
+
const linkOps = toCreate.map(
|
|
16067
16069
|
(e) => ctx.memoryEntityCollection.prepareCreate((record) => {
|
|
16068
16070
|
record._setRaw("memory_id", memoryId);
|
|
16069
16071
|
record._setRaw("entity_id", e.uniqueId);
|
|
16070
16072
|
if (userId !== void 0) record._setRaw("user_id", userId);
|
|
16071
16073
|
})
|
|
16072
16074
|
);
|
|
16073
|
-
await ctx.database.batch(...
|
|
16075
|
+
await ctx.database.batch(...entityOps, ...linkOps);
|
|
16074
16076
|
});
|
|
16075
16077
|
return skipped ? [] : entities;
|
|
16076
16078
|
}
|
|
@@ -16085,22 +16087,28 @@ async function autoLinkBlocked(ctx, memoryId) {
|
|
|
16085
16087
|
}
|
|
16086
16088
|
async function replaceMemoryEntitiesGuardedOp(ctx, memoryId, entityInputs) {
|
|
16087
16089
|
const normalized = entityInputs.map((e) => typeof e === "string" ? { name: e } : e);
|
|
16088
|
-
const byName = await upsertEntitiesOp(ctx, normalized);
|
|
16089
|
-
const entities = Array.from(byName.values());
|
|
16090
16090
|
const userId = ctx.userId;
|
|
16091
16091
|
let skipped = false;
|
|
16092
|
+
let entities = [];
|
|
16092
16093
|
await ctx.database.write(async () => {
|
|
16093
16094
|
if (await autoLinkBlocked(ctx, memoryId)) {
|
|
16094
16095
|
skipped = true;
|
|
16095
16096
|
return;
|
|
16096
16097
|
}
|
|
16098
|
+
const { entities: byName, operations: entityOps } = await upsertEntitiesInWrite(
|
|
16099
|
+
ctx,
|
|
16100
|
+
normalized
|
|
16101
|
+
);
|
|
16102
|
+
entities = Array.from(byName.values());
|
|
16097
16103
|
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb2.Q.where("memory_id", memoryId)).fetch();
|
|
16098
16104
|
const keep = new Set(entities.map((e) => e.uniqueId));
|
|
16099
16105
|
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
16100
16106
|
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
16101
16107
|
const toDestroy = existingLinks.filter((l) => !keep.has(String(l.entityId)));
|
|
16102
|
-
if (toCreate.length === 0 && toDestroy.length === 0) return;
|
|
16108
|
+
if (entityOps.length === 0 && toCreate.length === 0 && toDestroy.length === 0) return;
|
|
16109
|
+
const orphans = await findOrphanedEntities(ctx, memoryId, toDestroy);
|
|
16103
16110
|
await ctx.database.batch(
|
|
16111
|
+
...entityOps,
|
|
16104
16112
|
...toCreate.map(
|
|
16105
16113
|
(e) => ctx.memoryEntityCollection.prepareCreate((record) => {
|
|
16106
16114
|
record._setRaw("memory_id", memoryId);
|
|
@@ -16108,11 +16116,23 @@ async function replaceMemoryEntitiesGuardedOp(ctx, memoryId, entityInputs) {
|
|
|
16108
16116
|
if (userId !== void 0) record._setRaw("user_id", userId);
|
|
16109
16117
|
})
|
|
16110
16118
|
),
|
|
16111
|
-
...toDestroy.map((l) => l.prepareDestroyPermanently())
|
|
16119
|
+
...toDestroy.map((l) => l.prepareDestroyPermanently()),
|
|
16120
|
+
...orphans.map((e) => e.prepareDestroyPermanently())
|
|
16112
16121
|
);
|
|
16113
16122
|
});
|
|
16114
16123
|
return skipped ? null : entities;
|
|
16115
16124
|
}
|
|
16125
|
+
async function findOrphanedEntities(ctx, memoryId, toDestroy) {
|
|
16126
|
+
const candidateIds = [...new Set(toDestroy.map((l) => String(l.entityId)))];
|
|
16127
|
+
if (candidateIds.length === 0) return [];
|
|
16128
|
+
const links = await ctx.memoryEntityCollection.query(import_watermelondb2.Q.where("entity_id", import_watermelondb2.Q.oneOf(candidateIds))).fetch();
|
|
16129
|
+
const stillLinked = new Set(
|
|
16130
|
+
links.filter((l) => String(l.memoryId) !== memoryId).map((l) => String(l.entityId))
|
|
16131
|
+
);
|
|
16132
|
+
const orphanIds = candidateIds.filter((id) => !stillLinked.has(id));
|
|
16133
|
+
if (orphanIds.length === 0) return [];
|
|
16134
|
+
return await ctx.entityCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(orphanIds))).fetch();
|
|
16135
|
+
}
|
|
16116
16136
|
async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
16117
16137
|
if (memoryIds.length === 0) return;
|
|
16118
16138
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb2.Q.where("memory_id", import_watermelondb2.Q.oneOf(Array.from(memoryIds)))).fetch();
|
|
@@ -16733,7 +16753,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
|
|
|
16733
16753
|
(record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
16734
16754
|
);
|
|
16735
16755
|
}
|
|
16736
|
-
var TOPICS_EXTRACTION_VERSION =
|
|
16756
|
+
var TOPICS_EXTRACTION_VERSION = 3;
|
|
16737
16757
|
async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
|
|
16738
16758
|
const entityCtx = ctx.entityCtx;
|
|
16739
16759
|
if (!entityCtx) {
|
|
@@ -19554,7 +19574,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
19554
19574
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
19555
19575
|
);
|
|
19556
19576
|
}
|
|
19557
|
-
const { recall: recall2 } = await import("./recall-
|
|
19577
|
+
const { recall: recall2 } = await import("./recall-VDMDNQNB.mjs");
|
|
19558
19578
|
const result = await recall2(
|
|
19559
19579
|
query,
|
|
19560
19580
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|