@anuma/sdk 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/{chunk-N4FEY34G.mjs → chunk-7PAISHUN.mjs} +134 -3
- package/dist/expo/index.cjs +341 -19
- package/dist/expo/index.d.mts +176 -2
- package/dist/expo/index.d.ts +176 -2
- package/dist/expo/index.mjs +208 -19
- package/dist/expo/{recall-DHOR5WWW.mjs → recall-62ZPSDHR.mjs} +1 -1
- package/dist/react/{chunk-63IW5BS5.mjs → chunk-KRNJVLI6.mjs} +135 -3
- package/dist/react/index.cjs +361 -26
- package/dist/react/index.d.mts +216 -6
- package/dist/react/index.d.ts +216 -6
- package/dist/react/index.mjs +226 -26
- package/dist/react/{recall-PUXEQHAP.mjs → recall-ASTJPM5Z.mjs} +1 -1
- package/dist/server/{chunk-45GOZ3AB.mjs → chunk-KEMPJE6C.mjs} +134 -3
- package/dist/server/index.cjs +341 -19
- package/dist/server/index.d.mts +176 -2
- package/dist/server/index.d.ts +176 -2
- package/dist/server/index.mjs +208 -19
- package/dist/server/{recall-RMBNCEG6.mjs → recall-K2YHLBBV.mjs} +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -4160,14 +4160,19 @@ async function upsertEntitiesOp(ctx, entities) {
|
|
|
4160
4160
|
return out;
|
|
4161
4161
|
});
|
|
4162
4162
|
}
|
|
4163
|
-
async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs) {
|
|
4163
|
+
async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
4164
4164
|
if (entityInputs.length === 0) return [];
|
|
4165
4165
|
const normalized = entityInputs.map((e) => typeof e === "string" ? { name: e } : e);
|
|
4166
4166
|
const byName = await upsertEntitiesOp(ctx, normalized);
|
|
4167
4167
|
const entities = Array.from(byName.values());
|
|
4168
4168
|
if (entities.length === 0) return [];
|
|
4169
4169
|
const userId = ctx.userId;
|
|
4170
|
+
let skipped = false;
|
|
4170
4171
|
await ctx.database.write(async () => {
|
|
4172
|
+
if (options?.unlessTopicsUserManaged && await autoLinkBlocked(ctx, memoryId)) {
|
|
4173
|
+
skipped = true;
|
|
4174
|
+
return;
|
|
4175
|
+
}
|
|
4171
4176
|
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("memory_id", memoryId)).fetch();
|
|
4172
4177
|
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
4173
4178
|
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
@@ -4181,7 +4186,46 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs) {
|
|
|
4181
4186
|
);
|
|
4182
4187
|
await ctx.database.batch(...prepared);
|
|
4183
4188
|
});
|
|
4184
|
-
return entities;
|
|
4189
|
+
return skipped ? [] : entities;
|
|
4190
|
+
}
|
|
4191
|
+
async function autoLinkBlocked(ctx, memoryId) {
|
|
4192
|
+
try {
|
|
4193
|
+
const rows = await ctx.database.get("memory_vault").query(import_watermelondb9.Q.where("id", memoryId)).fetch();
|
|
4194
|
+
const row = rows[0];
|
|
4195
|
+
return !row || !!row.isDeleted || !!row.topicsUserManaged;
|
|
4196
|
+
} catch {
|
|
4197
|
+
return true;
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
async function replaceMemoryEntitiesGuardedOp(ctx, memoryId, entityInputs) {
|
|
4201
|
+
const normalized = entityInputs.map((e) => typeof e === "string" ? { name: e } : e);
|
|
4202
|
+
const byName = await upsertEntitiesOp(ctx, normalized);
|
|
4203
|
+
const entities = Array.from(byName.values());
|
|
4204
|
+
const userId = ctx.userId;
|
|
4205
|
+
let skipped = false;
|
|
4206
|
+
await ctx.database.write(async () => {
|
|
4207
|
+
if (await autoLinkBlocked(ctx, memoryId)) {
|
|
4208
|
+
skipped = true;
|
|
4209
|
+
return;
|
|
4210
|
+
}
|
|
4211
|
+
const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb9.Q.where("memory_id", memoryId)).fetch();
|
|
4212
|
+
const keep = new Set(entities.map((e) => e.uniqueId));
|
|
4213
|
+
const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
|
|
4214
|
+
const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
|
|
4215
|
+
const toDestroy = existingLinks.filter((l) => !keep.has(String(l.entityId)));
|
|
4216
|
+
if (toCreate.length === 0 && toDestroy.length === 0) return;
|
|
4217
|
+
await ctx.database.batch(
|
|
4218
|
+
...toCreate.map(
|
|
4219
|
+
(e) => ctx.memoryEntityCollection.prepareCreate((record) => {
|
|
4220
|
+
record._setRaw("memory_id", memoryId);
|
|
4221
|
+
record._setRaw("entity_id", e.uniqueId);
|
|
4222
|
+
if (userId !== void 0) record._setRaw("user_id", userId);
|
|
4223
|
+
})
|
|
4224
|
+
),
|
|
4225
|
+
...toDestroy.map((l) => l.prepareDestroyPermanently())
|
|
4226
|
+
);
|
|
4227
|
+
});
|
|
4228
|
+
return skipped ? null : entities;
|
|
4185
4229
|
}
|
|
4186
4230
|
async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
4187
4231
|
if (memoryIds.length === 0) return;
|
|
@@ -4339,6 +4383,7 @@ function vaultMemoryToStoredRaw(memory) {
|
|
|
4339
4383
|
eventTimeEnd: memory.eventTimeEnd ?? null,
|
|
4340
4384
|
eventTimeKind: memory.eventTimeKind ?? null,
|
|
4341
4385
|
topicsUserManaged: memory.topicsUserManaged ?? false,
|
|
4386
|
+
topicsExtractedAt: memory.topicsExtractedAt ?? null,
|
|
4342
4387
|
createdAt: memory.createdAt,
|
|
4343
4388
|
updatedAt: memory.updatedAt,
|
|
4344
4389
|
isDeleted: memory.isDeleted
|
|
@@ -4522,6 +4567,7 @@ function vaultMemoryRawToStoredRaw(raw) {
|
|
|
4522
4567
|
eventTimeKind: raw.event_time_kind ?? null,
|
|
4523
4568
|
// SQLite stores booleans as 0/1, LokiJS as true/false — coerce both.
|
|
4524
4569
|
topicsUserManaged: raw.topics_user_managed === true || raw.topics_user_managed === 1,
|
|
4570
|
+
topicsExtractedAt: raw.topics_extracted_at ?? null,
|
|
4525
4571
|
createdAt: new Date(raw.created_at),
|
|
4526
4572
|
updatedAt: new Date(raw.updated_at),
|
|
4527
4573
|
isDeleted: raw.is_deleted === true || raw.is_deleted === 1
|
|
@@ -4674,6 +4720,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId) {
|
|
|
4674
4720
|
await ctx.database.write(async () => {
|
|
4675
4721
|
await record.update((r) => {
|
|
4676
4722
|
r._setRaw("topics_user_managed", false);
|
|
4723
|
+
r._setRaw("topics_extracted_at", null);
|
|
4677
4724
|
r._setRaw("updated_at", originalUpdatedAt);
|
|
4678
4725
|
});
|
|
4679
4726
|
});
|
|
@@ -4717,6 +4764,87 @@ async function getUnfiledVaultMemoriesOp(ctx) {
|
|
|
4717
4764
|
(record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
4718
4765
|
);
|
|
4719
4766
|
}
|
|
4767
|
+
async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
|
|
4768
|
+
const entityCtx = ctx.entityCtx;
|
|
4769
|
+
if (!entityCtx) {
|
|
4770
|
+
throw new Error("getMemoriesNeedingTopicExtractionOp requires ctx.entityCtx");
|
|
4771
|
+
}
|
|
4772
|
+
const conditions = [
|
|
4773
|
+
// Boolean optional column: null (legacy) and false both mean auto-managed.
|
|
4774
|
+
// Q.notEq(true) is a NULL trap on SQLite (NULL <> TRUE is NULL) — enumerate.
|
|
4775
|
+
import_watermelondb10.Q.or(import_watermelondb10.Q.where("topics_user_managed", null), import_watermelondb10.Q.where("topics_user_managed", false)),
|
|
4776
|
+
...baseVaultConditions(ctx),
|
|
4777
|
+
import_watermelondb10.Q.sortBy("created_at", import_watermelondb10.Q.desc)
|
|
4778
|
+
];
|
|
4779
|
+
const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
|
|
4780
|
+
const stampedPending = [];
|
|
4781
|
+
const unstamped = [];
|
|
4782
|
+
for (const raw of rows) {
|
|
4783
|
+
const stamp = raw.topics_extracted_at ?? null;
|
|
4784
|
+
if (stamp !== null) {
|
|
4785
|
+
if (raw.updated_at > stamp) stampedPending.push(raw);
|
|
4786
|
+
} else {
|
|
4787
|
+
unstamped.push(raw);
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
const linkedIds = /* @__PURE__ */ new Set();
|
|
4791
|
+
const CHUNK = 500;
|
|
4792
|
+
for (let i = 0; i < unstamped.length; i += CHUNK) {
|
|
4793
|
+
const ids = unstamped.slice(i, i + CHUNK).map((r) => r.id);
|
|
4794
|
+
const links = await entityCtx.memoryEntityCollection.query(import_watermelondb10.Q.where("memory_id", import_watermelondb10.Q.oneOf(ids))).unsafeFetchRaw();
|
|
4795
|
+
for (const link of links) linkedIds.add(String(link.memory_id));
|
|
4796
|
+
}
|
|
4797
|
+
const linkedUnstampedAll = [];
|
|
4798
|
+
const pendingRaw = [...stampedPending];
|
|
4799
|
+
for (const raw of unstamped) {
|
|
4800
|
+
if (linkedIds.has(raw.id)) {
|
|
4801
|
+
linkedUnstampedAll.push(raw.id);
|
|
4802
|
+
} else {
|
|
4803
|
+
pendingRaw.push(raw);
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
const cap = options?.limit !== void 0 && options.limit > 0 ? options.limit : void 0;
|
|
4807
|
+
const limitedPendingRaw = cap !== void 0 ? pendingRaw.slice(0, cap) : pendingRaw;
|
|
4808
|
+
const linkedUnstamped = cap !== void 0 ? linkedUnstampedAll.slice(0, cap) : linkedUnstampedAll;
|
|
4809
|
+
const pending = await mapInBatches(
|
|
4810
|
+
limitedPendingRaw,
|
|
4811
|
+
(raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
4812
|
+
);
|
|
4813
|
+
return { pending, linkedUnstamped };
|
|
4814
|
+
}
|
|
4815
|
+
async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt) {
|
|
4816
|
+
if (memoryIds.length === 0) return [];
|
|
4817
|
+
const uniqueIds = Array.from(new Set(memoryIds));
|
|
4818
|
+
const CHUNK = 500;
|
|
4819
|
+
const stamped = [];
|
|
4820
|
+
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
4821
|
+
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
4822
|
+
await ctx.database.write(async () => {
|
|
4823
|
+
const prepared = [];
|
|
4824
|
+
for (const id of chunkIds) {
|
|
4825
|
+
let record;
|
|
4826
|
+
try {
|
|
4827
|
+
record = await ctx.vaultMemoryCollection.find(id);
|
|
4828
|
+
} catch {
|
|
4829
|
+
continue;
|
|
4830
|
+
}
|
|
4831
|
+
if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.topicsUserManaged) {
|
|
4832
|
+
continue;
|
|
4833
|
+
}
|
|
4834
|
+
const originalUpdatedAt = record.updatedAt.getTime();
|
|
4835
|
+
prepared.push(
|
|
4836
|
+
record.prepareUpdate((r) => {
|
|
4837
|
+
r._setRaw("topics_extracted_at", extractedAt);
|
|
4838
|
+
r._setRaw("updated_at", originalUpdatedAt);
|
|
4839
|
+
})
|
|
4840
|
+
);
|
|
4841
|
+
stamped.push(id);
|
|
4842
|
+
}
|
|
4843
|
+
if (prepared.length > 0) await ctx.database.batch(...prepared);
|
|
4844
|
+
});
|
|
4845
|
+
}
|
|
4846
|
+
return stamped;
|
|
4847
|
+
}
|
|
4720
4848
|
async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
4721
4849
|
if (ctx.userId !== void 0 && ctx.userId !== userId) return 0;
|
|
4722
4850
|
const records = await ctx.vaultMemoryCollection.query(import_watermelondb10.Q.where("user_id", userId), import_watermelondb10.Q.where("is_deleted", false)).fetch();
|
|
@@ -7036,6 +7164,7 @@ __export(index_exports, {
|
|
|
7036
7164
|
StoredVaultMemoryModel: () => VaultMemory,
|
|
7037
7165
|
StreamExpiredError: () => StreamExpiredError,
|
|
7038
7166
|
THEME_ATTRS: () => THEME_ATTRS,
|
|
7167
|
+
TOPIC_EXTRACTION_BATCH_SIZE: () => TOPIC_EXTRACTION_BATCH_SIZE,
|
|
7039
7168
|
TextProcessor: () => TextProcessor,
|
|
7040
7169
|
UIInteractionProvider: () => UIInteractionProvider,
|
|
7041
7170
|
WalletPoller: () => WalletPoller,
|
|
@@ -7127,7 +7256,9 @@ __export(index_exports, {
|
|
|
7127
7256
|
exportElementToPdf: () => exportElementToPdf,
|
|
7128
7257
|
exportMarkdownToPdf: () => exportMarkdownToPdf,
|
|
7129
7258
|
exportPublicKey: () => exportPublicKey,
|
|
7259
|
+
extractAndLinkEntitiesForMemoriesOp: () => extractAndLinkEntitiesForMemoriesOp,
|
|
7130
7260
|
extractAndRetain: () => extractAndRetain,
|
|
7261
|
+
extractEntitiesForMemories: () => extractEntitiesForMemories,
|
|
7131
7262
|
extractFacts: () => extractFacts,
|
|
7132
7263
|
extractFileIds: () => extractFileIds,
|
|
7133
7264
|
fileExists: () => fileExists,
|
|
@@ -7183,6 +7314,7 @@ __export(index_exports, {
|
|
|
7183
7314
|
getMediaOp: () => getMediaOp,
|
|
7184
7315
|
getMediaTypeFromMime: () => getMediaTypeFromMime,
|
|
7185
7316
|
getMemoriesByEntityNamesOp: () => getMemoriesByEntityNamesOp,
|
|
7317
|
+
getMemoriesNeedingTopicExtractionOp: () => getMemoriesNeedingTopicExtractionOp,
|
|
7186
7318
|
getNotionAccessToken: () => getNotionAccessToken,
|
|
7187
7319
|
getNotionMCPUrl: () => getNotionMCPUrl,
|
|
7188
7320
|
getNumberAttr: () => getNumberAttr,
|
|
@@ -7263,6 +7395,7 @@ __export(index_exports, {
|
|
|
7263
7395
|
renderAnumaTree: () => renderAnumaTree,
|
|
7264
7396
|
renderElementToCanvas: () => renderElementToCanvas,
|
|
7265
7397
|
replaceById: () => replaceById,
|
|
7398
|
+
replaceMemoryEntitiesGuardedOp: () => replaceMemoryEntitiesGuardedOp,
|
|
7266
7399
|
requestEncryptionKey: () => requestEncryptionKey,
|
|
7267
7400
|
requestKeyPair: () => requestKeyPair,
|
|
7268
7401
|
resolveFilePlaceholders: () => resolveFilePlaceholders,
|
|
@@ -7288,6 +7421,7 @@ __export(index_exports, {
|
|
|
7288
7421
|
settingsStorageSchema: () => settingsStorageSchema,
|
|
7289
7422
|
shouldChunkMessage: () => shouldChunkMessage,
|
|
7290
7423
|
shouldRefreshTools: () => shouldRefreshTools,
|
|
7424
|
+
stampTopicsExtractedAtOp: () => stampTopicsExtractedAtOp,
|
|
7291
7425
|
startGithubAuth: () => startGithubAuth,
|
|
7292
7426
|
startNotionAuth: () => startNotionAuth,
|
|
7293
7427
|
storeCalendarPendingMessage: () => storeCalendarPendingMessage,
|
|
@@ -13901,6 +14035,9 @@ __decorateClass([
|
|
|
13901
14035
|
__decorateClass([
|
|
13902
14036
|
(0, import_decorators3.field)("topics_user_managed")
|
|
13903
14037
|
], VaultMemory.prototype, "topicsUserManaged", 2);
|
|
14038
|
+
__decorateClass([
|
|
14039
|
+
(0, import_decorators3.field)("topics_extracted_at")
|
|
14040
|
+
], VaultMemory.prototype, "topicsExtractedAt", 2);
|
|
13904
14041
|
__decorateClass([
|
|
13905
14042
|
import_decorators3.readonly,
|
|
13906
14043
|
(0, import_decorators3.date)("created_at")
|
|
@@ -14132,7 +14269,7 @@ async function isMemoryTopicsUserManaged(ctx, memoryId) {
|
|
|
14132
14269
|
return true;
|
|
14133
14270
|
}
|
|
14134
14271
|
}
|
|
14135
|
-
var
|
|
14272
|
+
var DEFAULT_EXTRACTION_MODEL = "gpt-oss/gpt-oss-120b";
|
|
14136
14273
|
var DEFAULT_MIN_CONFIDENCE = 0.7;
|
|
14137
14274
|
var MAX_CONTENT_LENGTH = 200;
|
|
14138
14275
|
var MIN_CONTENT_LENGTH = 3;
|
|
@@ -14145,6 +14282,16 @@ var FACT_TYPES = [
|
|
|
14145
14282
|
"constraint",
|
|
14146
14283
|
"other"
|
|
14147
14284
|
];
|
|
14285
|
+
var ENTITY_KIND_GUIDELINES = `Choose the MOST SPECIFIC kind:
|
|
14286
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
14287
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
14288
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
14289
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
14290
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
14291
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
14292
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
14293
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
14294
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits.`;
|
|
14148
14295
|
var SYSTEM_PROMPT3 = `You extract durable user facts from conversations for a personal memory system.
|
|
14149
14296
|
|
|
14150
14297
|
A "durable fact" is something the user shared about themselves that should still be true in future conversations. Examples that ARE durable:
|
|
@@ -14173,16 +14320,7 @@ For each durable fact, output:
|
|
|
14173
14320
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
14174
14321
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
14175
14322
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
14176
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns.
|
|
14177
|
-
- person: a named individual ("Sara", "Dr. Lee")
|
|
14178
|
-
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
14179
|
-
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
14180
|
-
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
14181
|
-
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
14182
|
-
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
14183
|
-
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
14184
|
-
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
14185
|
-
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
14323
|
+
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Examples:
|
|
14186
14324
|
- "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization" }, { "name": "Haskell", "kind": "concept" }]
|
|
14187
14325
|
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
14188
14326
|
- eventTime: when the event in this fact occurs/occurred. Resolve relative phrases ("yesterday", "next week") against the current date given in the user message. Output one of:
|
|
@@ -14208,7 +14346,7 @@ async function extractFacts(messages, options) {
|
|
|
14208
14346
|
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
14209
14347
|
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
14210
14348
|
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
14211
|
-
model: options.model ??
|
|
14349
|
+
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
14212
14350
|
systemPrompt: SYSTEM_PROMPT3,
|
|
14213
14351
|
userMessage: `Today's date is ${today}. Resolve any relative dates ("yesterday", "next week") against it.
|
|
14214
14352
|
|
|
@@ -14302,7 +14440,9 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
14302
14440
|
if (options.entityCtx && candidate.entities.length > 0) {
|
|
14303
14441
|
try {
|
|
14304
14442
|
if (!await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
14305
|
-
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities
|
|
14443
|
+
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
14444
|
+
unlessTopicsUserManaged: true
|
|
14445
|
+
});
|
|
14306
14446
|
}
|
|
14307
14447
|
} catch (err) {
|
|
14308
14448
|
log.warn("[memory/extract] linkMemoryEntitiesOp failed", err);
|
|
@@ -14707,7 +14847,7 @@ init_logger();
|
|
|
14707
14847
|
init_portalLlm();
|
|
14708
14848
|
init_recall();
|
|
14709
14849
|
var DEFAULT_BASE_URL2 = BASE_URL;
|
|
14710
|
-
var
|
|
14850
|
+
var DEFAULT_MODEL3 = "anthropic/claude-sonnet-4-6";
|
|
14711
14851
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
14712
14852
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
14713
14853
|
var DEFAULT_SYSTEM_PROMPT = `You are a personal assistant with access to the user's memory. Answer the user's question using the supplied memories as evidence.
|
|
@@ -14739,7 +14879,7 @@ async function reflect(query, ctx, options) {
|
|
|
14739
14879
|
const evidence = recalled.memories.map((m, i) => `[${i + 1}] (id: ${m.id}, kind: ${m.kind})
|
|
14740
14880
|
${m.content}`).join("\n\n");
|
|
14741
14881
|
const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL2;
|
|
14742
|
-
const model = options.llmModel ??
|
|
14882
|
+
const model = options.llmModel ?? DEFAULT_MODEL3;
|
|
14743
14883
|
const wantsStructured = !!options.responseSchema;
|
|
14744
14884
|
const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
|
|
14745
14885
|
const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
@@ -14849,6 +14989,168 @@ function parseAnswer(body, base, parseSchema) {
|
|
|
14849
14989
|
};
|
|
14850
14990
|
}
|
|
14851
14991
|
|
|
14992
|
+
// src/lib/memory/topicExtract.ts
|
|
14993
|
+
init_operations2();
|
|
14994
|
+
init_operations3();
|
|
14995
|
+
init_logger();
|
|
14996
|
+
init_redactor();
|
|
14997
|
+
init_portalLlm();
|
|
14998
|
+
var TOPIC_EXTRACTION_BATCH_SIZE = 10;
|
|
14999
|
+
var MAX_CHARS_PER_MEMORY = 300;
|
|
15000
|
+
var MAX_VOCABULARY_NAMES = 100;
|
|
15001
|
+
var SYSTEM_PROMPT4 = `You assign topics to saved memories for a personal memory system.
|
|
15002
|
+
|
|
15003
|
+
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.
|
|
15004
|
+
|
|
15005
|
+
Include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES}
|
|
15006
|
+
|
|
15007
|
+
Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
|
|
15008
|
+
- exactly one element per input memory, echoing its id verbatim
|
|
15009
|
+
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
15010
|
+
No prose.`;
|
|
15011
|
+
async function extractEntitiesForMemories(memories, options) {
|
|
15012
|
+
const out = /* @__PURE__ */ new Map();
|
|
15013
|
+
if (memories.length === 0) return out;
|
|
15014
|
+
const redactor = resolvePiiRedactor(options.piiRedaction);
|
|
15015
|
+
const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
|
|
15016
|
+
const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
|
|
15017
|
+
When a memory refers to one of these, reuse the EXACT existing name (same spelling and casing) instead of a variant.
|
|
15018
|
+
|
|
15019
|
+
` : "";
|
|
15020
|
+
for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
|
|
15021
|
+
const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
|
|
15022
|
+
const listing = batch.map((m) => {
|
|
15023
|
+
const content = m.content.slice(0, MAX_CHARS_PER_MEMORY);
|
|
15024
|
+
return `[${m.id}] ${redactor ? redactor.redactText(content).text : content}`;
|
|
15025
|
+
}).join("\n");
|
|
15026
|
+
const parsed = await callPortalJsonCompletion({
|
|
15027
|
+
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
15028
|
+
...options.getToken !== void 0 && { getToken: options.getToken },
|
|
15029
|
+
...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
|
|
15030
|
+
model: options.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
15031
|
+
systemPrompt: SYSTEM_PROMPT4,
|
|
15032
|
+
userMessage: `${vocabularyNote}Memories:
|
|
15033
|
+
${listing}
|
|
15034
|
+
|
|
15035
|
+
List each memory's named entities.`,
|
|
15036
|
+
tag: "memory/topics",
|
|
15037
|
+
...options.fetchFn && { fetchFn: options.fetchFn },
|
|
15038
|
+
...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
|
|
15039
|
+
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
15040
|
+
...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
|
|
15041
|
+
...options.backoffMs && { backoffMs: options.backoffMs }
|
|
15042
|
+
});
|
|
15043
|
+
if (parsed === null) {
|
|
15044
|
+
getLogger().warn(
|
|
15045
|
+
`[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
|
|
15046
|
+
);
|
|
15047
|
+
continue;
|
|
15048
|
+
}
|
|
15049
|
+
const validIds = new Set(batch.map((m) => m.id));
|
|
15050
|
+
const byId = parseTopicResponse(parsed, validIds);
|
|
15051
|
+
if (byId === null) {
|
|
15052
|
+
getLogger().warn(
|
|
15053
|
+
`[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
|
|
15054
|
+
);
|
|
15055
|
+
continue;
|
|
15056
|
+
}
|
|
15057
|
+
for (const m of batch) {
|
|
15058
|
+
const entities = byId.get(m.id);
|
|
15059
|
+
if (entities === void 0) {
|
|
15060
|
+
continue;
|
|
15061
|
+
}
|
|
15062
|
+
out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
|
|
15063
|
+
}
|
|
15064
|
+
}
|
|
15065
|
+
return out;
|
|
15066
|
+
}
|
|
15067
|
+
function restoreEntities(entities, redactor) {
|
|
15068
|
+
return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
|
|
15069
|
+
(e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
|
|
15070
|
+
);
|
|
15071
|
+
}
|
|
15072
|
+
function parseTopicResponse(parsed, validIds) {
|
|
15073
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
15074
|
+
const list = parsed.memories;
|
|
15075
|
+
if (!Array.isArray(list)) return null;
|
|
15076
|
+
const out = /* @__PURE__ */ new Map();
|
|
15077
|
+
for (const raw of list) {
|
|
15078
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
15079
|
+
const obj = raw;
|
|
15080
|
+
if (typeof obj.id !== "string" || !validIds.has(obj.id) || out.has(obj.id)) continue;
|
|
15081
|
+
const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
|
|
15082
|
+
out.set(obj.id, entities);
|
|
15083
|
+
}
|
|
15084
|
+
return out;
|
|
15085
|
+
}
|
|
15086
|
+
async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
|
|
15087
|
+
const entityCtx = ctx.entityCtx;
|
|
15088
|
+
if (!entityCtx) {
|
|
15089
|
+
throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
|
|
15090
|
+
}
|
|
15091
|
+
const log = getLogger();
|
|
15092
|
+
const extractedAt = options.now ?? Date.now();
|
|
15093
|
+
const skippedIds = [];
|
|
15094
|
+
const inputs = [];
|
|
15095
|
+
for (const id of memoryIds) {
|
|
15096
|
+
let record;
|
|
15097
|
+
try {
|
|
15098
|
+
record = await ctx.vaultMemoryCollection.find(id);
|
|
15099
|
+
} catch {
|
|
15100
|
+
skippedIds.push(id);
|
|
15101
|
+
continue;
|
|
15102
|
+
}
|
|
15103
|
+
if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
|
|
15104
|
+
skippedIds.push(id);
|
|
15105
|
+
continue;
|
|
15106
|
+
}
|
|
15107
|
+
try {
|
|
15108
|
+
const stored = await vaultMemoryToStored(
|
|
15109
|
+
record,
|
|
15110
|
+
ctx.walletAddress,
|
|
15111
|
+
ctx.signMessage,
|
|
15112
|
+
ctx.embeddedWalletSigner
|
|
15113
|
+
);
|
|
15114
|
+
inputs.push({ id, content: stored.content });
|
|
15115
|
+
} catch (err) {
|
|
15116
|
+
log.warn("[memory/topics] failed to load memory for extraction", err);
|
|
15117
|
+
skippedIds.push(id);
|
|
15118
|
+
}
|
|
15119
|
+
}
|
|
15120
|
+
const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
|
|
15121
|
+
const toStamp = [];
|
|
15122
|
+
for (const input of inputs) {
|
|
15123
|
+
const entities = entitiesByMemory.get(input.id);
|
|
15124
|
+
if (entities === void 0) {
|
|
15125
|
+
skippedIds.push(input.id);
|
|
15126
|
+
continue;
|
|
15127
|
+
}
|
|
15128
|
+
try {
|
|
15129
|
+
const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
|
|
15130
|
+
if (linked === null) {
|
|
15131
|
+
skippedIds.push(input.id);
|
|
15132
|
+
entitiesByMemory.delete(input.id);
|
|
15133
|
+
continue;
|
|
15134
|
+
}
|
|
15135
|
+
} catch (err) {
|
|
15136
|
+
log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
|
|
15137
|
+
skippedIds.push(input.id);
|
|
15138
|
+
entitiesByMemory.delete(input.id);
|
|
15139
|
+
continue;
|
|
15140
|
+
}
|
|
15141
|
+
toStamp.push(input.id);
|
|
15142
|
+
}
|
|
15143
|
+
const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
|
|
15144
|
+
const stampedSet = new Set(stampedIds);
|
|
15145
|
+
for (const id of toStamp) {
|
|
15146
|
+
if (!stampedSet.has(id)) {
|
|
15147
|
+
skippedIds.push(id);
|
|
15148
|
+
entitiesByMemory.delete(id);
|
|
15149
|
+
}
|
|
15150
|
+
}
|
|
15151
|
+
return { entitiesByMemory, stampedIds, skippedIds };
|
|
15152
|
+
}
|
|
15153
|
+
|
|
14852
15154
|
// src/lib/memoryEngine/index.ts
|
|
14853
15155
|
init_chunking();
|
|
14854
15156
|
init_embeddings();
|
|
@@ -19218,7 +19520,7 @@ __decorateClass([
|
|
|
19218
19520
|
], VaultFolder.prototype, "context", 2);
|
|
19219
19521
|
|
|
19220
19522
|
// src/lib/db/schema.ts
|
|
19221
|
-
var SDK_SCHEMA_VERSION =
|
|
19523
|
+
var SDK_SCHEMA_VERSION = 36;
|
|
19222
19524
|
var sdkSchema = (0, import_watermelondb20.appSchema)({
|
|
19223
19525
|
version: SDK_SCHEMA_VERSION,
|
|
19224
19526
|
tables: [
|
|
@@ -19339,7 +19641,11 @@ var sdkSchema = (0, import_watermelondb20.appSchema)({
|
|
|
19339
19641
|
// When true, the user has manually set this memory's topics (entity
|
|
19340
19642
|
// links). Auto-extraction then leaves its links alone — the user owns
|
|
19341
19643
|
// them. Null/false = topics are auto-derived (default).
|
|
19342
|
-
{ name: "topics_user_managed", type: "boolean", isOptional: true }
|
|
19644
|
+
{ name: "topics_user_managed", type: "boolean", isOptional: true },
|
|
19645
|
+
// Unix ms of the last LLM topic-extraction pass over this memory's
|
|
19646
|
+
// content. Null = never extracted standalone (legacy rows with entity
|
|
19647
|
+
// links are grandfathered — see getMemoriesNeedingTopicExtractionOp).
|
|
19648
|
+
{ name: "topics_extracted_at", type: "number", isOptional: true }
|
|
19343
19649
|
]
|
|
19344
19650
|
}),
|
|
19345
19651
|
// Entity table — canonical names extracted from auto-extraction (W5).
|
|
@@ -19937,6 +20243,19 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
|
|
|
19937
20243
|
]
|
|
19938
20244
|
})
|
|
19939
20245
|
]
|
|
20246
|
+
},
|
|
20247
|
+
// v35 -> v36: topics_extracted_at watermark on memory_vault. Existing rows
|
|
20248
|
+
// keep it NULL — rows that already have entity links are grandfathered as
|
|
20249
|
+
// extracted (no mass re-extraction on upgrade), rows without links are the
|
|
20250
|
+
// backfill target. See getMemoriesNeedingTopicExtractionOp.
|
|
20251
|
+
{
|
|
20252
|
+
toVersion: 36,
|
|
20253
|
+
steps: [
|
|
20254
|
+
(0, import_migrations2.addColumns)({
|
|
20255
|
+
table: "memory_vault",
|
|
20256
|
+
columns: [{ name: "topics_extracted_at", type: "number", isOptional: true }]
|
|
20257
|
+
})
|
|
20258
|
+
]
|
|
19940
20259
|
}
|
|
19941
20260
|
]
|
|
19942
20261
|
});
|
|
@@ -21447,7 +21766,7 @@ function startObserve(entry, walletAddress) {
|
|
|
21447
21766
|
isInitialEmission = false;
|
|
21448
21767
|
}
|
|
21449
21768
|
function subscribeUserSettings(database, walletAddress, listener) {
|
|
21450
|
-
if (!walletAddress) return () => void 0;
|
|
21769
|
+
if (!database || !walletAddress) return () => void 0;
|
|
21451
21770
|
const perDb = getOrCreatePerDb(database);
|
|
21452
21771
|
let entry = perDb.get(walletAddress);
|
|
21453
21772
|
if (!entry) {
|
|
@@ -21477,17 +21796,18 @@ function subscribeUserSettings(database, walletAddress, listener) {
|
|
|
21477
21796
|
};
|
|
21478
21797
|
}
|
|
21479
21798
|
function getUserSettingsSnapshot(database, walletAddress) {
|
|
21480
|
-
if (!walletAddress) return EMPTY_SNAPSHOT;
|
|
21799
|
+
if (!database || !walletAddress) return EMPTY_SNAPSHOT;
|
|
21481
21800
|
return pool.get(database)?.get(walletAddress)?.snapshot ?? EMPTY_SNAPSHOT;
|
|
21482
21801
|
}
|
|
21483
21802
|
function patchUserSettingsSnapshot(database, walletAddress, patch) {
|
|
21484
|
-
if (!walletAddress) return;
|
|
21803
|
+
if (!database || !walletAddress) return;
|
|
21485
21804
|
const entry = pool.get(database)?.get(walletAddress);
|
|
21486
21805
|
if (!entry) return;
|
|
21487
21806
|
patchSnapshot(entry, patch);
|
|
21488
21807
|
}
|
|
21489
21808
|
|
|
21490
21809
|
// src/react/useSettings.ts
|
|
21810
|
+
var DB_NOT_READY = "Database not ready";
|
|
21491
21811
|
function useSettings(options) {
|
|
21492
21812
|
const { database, walletAddress } = options;
|
|
21493
21813
|
const subscribe = (0, import_react9.useCallback)(
|
|
@@ -21500,24 +21820,25 @@ function useSettings(options) {
|
|
|
21500
21820
|
);
|
|
21501
21821
|
const snapshot = (0, import_react9.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
21502
21822
|
const storageCtx = (0, import_react9.useMemo)(
|
|
21503
|
-
() =>
|
|
21823
|
+
() => database ? {
|
|
21504
21824
|
database,
|
|
21505
21825
|
userPreferencesCollection: database.get("userPreferences"),
|
|
21506
21826
|
modelPreferencesCollection: database.get("modelPreferences")
|
|
21507
|
-
}
|
|
21827
|
+
} : null,
|
|
21508
21828
|
[database]
|
|
21509
21829
|
);
|
|
21510
21830
|
const legacyStorageCtx = (0, import_react9.useMemo)(
|
|
21511
|
-
() =>
|
|
21831
|
+
() => database ? {
|
|
21512
21832
|
database,
|
|
21513
21833
|
modelPreferencesCollection: database.get("modelPreferences")
|
|
21514
|
-
}
|
|
21834
|
+
} : null,
|
|
21515
21835
|
[database]
|
|
21516
21836
|
);
|
|
21517
21837
|
const getModelPreference = (0, import_react9.useCallback)(
|
|
21518
21838
|
async (address) => {
|
|
21519
21839
|
try {
|
|
21520
21840
|
if (!address) throw new Error("Wallet address is required");
|
|
21841
|
+
if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
|
|
21521
21842
|
const result = await getModelPreferenceOp(legacyStorageCtx, address);
|
|
21522
21843
|
return result;
|
|
21523
21844
|
} catch (error) {
|
|
@@ -21530,6 +21851,7 @@ function useSettings(options) {
|
|
|
21530
21851
|
async (address, models) => {
|
|
21531
21852
|
try {
|
|
21532
21853
|
if (!address) throw new Error("Wallet address is required");
|
|
21854
|
+
if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
|
|
21533
21855
|
const result = await setModelPreferenceOp(legacyStorageCtx, address, models);
|
|
21534
21856
|
if (walletAddress && address === walletAddress) {
|
|
21535
21857
|
patchUserSettingsSnapshot(database, walletAddress, { modelPreference: result });
|
|
@@ -21545,6 +21867,7 @@ function useSettings(options) {
|
|
|
21545
21867
|
async (address) => {
|
|
21546
21868
|
try {
|
|
21547
21869
|
if (!address) throw new Error("Wallet address is required");
|
|
21870
|
+
if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
|
|
21548
21871
|
const deleted = await deleteModelPreferenceOp(legacyStorageCtx, address);
|
|
21549
21872
|
if (deleted && walletAddress && address === walletAddress) {
|
|
21550
21873
|
patchUserSettingsSnapshot(database, walletAddress, { modelPreference: null });
|
|
@@ -21560,6 +21883,7 @@ function useSettings(options) {
|
|
|
21560
21883
|
async (address) => {
|
|
21561
21884
|
try {
|
|
21562
21885
|
if (!address) throw new Error("Wallet address is required");
|
|
21886
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21563
21887
|
const result = await getUserPreferenceOp(storageCtx, address);
|
|
21564
21888
|
return result;
|
|
21565
21889
|
} catch (error) {
|
|
@@ -21572,6 +21896,7 @@ function useSettings(options) {
|
|
|
21572
21896
|
async (address, opts) => {
|
|
21573
21897
|
try {
|
|
21574
21898
|
if (!address) throw new Error("Wallet address is required");
|
|
21899
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21575
21900
|
const result = await setUserPreferenceOp(storageCtx, address, opts);
|
|
21576
21901
|
if (walletAddress && address === walletAddress) {
|
|
21577
21902
|
patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
|
|
@@ -21587,6 +21912,7 @@ function useSettings(options) {
|
|
|
21587
21912
|
async (address, profile) => {
|
|
21588
21913
|
try {
|
|
21589
21914
|
if (!address) throw new Error("Wallet address is required");
|
|
21915
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21590
21916
|
const result = await updateProfileOp(storageCtx, address, profile);
|
|
21591
21917
|
if (result && walletAddress && address === walletAddress) {
|
|
21592
21918
|
patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
|
|
@@ -21602,6 +21928,7 @@ function useSettings(options) {
|
|
|
21602
21928
|
async (address, personality) => {
|
|
21603
21929
|
try {
|
|
21604
21930
|
if (!address) throw new Error("Wallet address is required");
|
|
21931
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21605
21932
|
const result = await updatePersonalityOp(storageCtx, address, personality);
|
|
21606
21933
|
if (result && walletAddress && address === walletAddress) {
|
|
21607
21934
|
patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
|
|
@@ -21617,6 +21944,7 @@ function useSettings(options) {
|
|
|
21617
21944
|
async (address, models) => {
|
|
21618
21945
|
try {
|
|
21619
21946
|
if (!address) throw new Error("Wallet address is required");
|
|
21947
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21620
21948
|
const result = await updateModelsOp(storageCtx, address, models);
|
|
21621
21949
|
if (result && walletAddress && address === walletAddress) {
|
|
21622
21950
|
patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
|
|
@@ -21632,6 +21960,7 @@ function useSettings(options) {
|
|
|
21632
21960
|
async (address) => {
|
|
21633
21961
|
try {
|
|
21634
21962
|
if (!address) throw new Error("Wallet address is required");
|
|
21963
|
+
if (!storageCtx) throw new Error(DB_NOT_READY);
|
|
21635
21964
|
const deleted = await deleteUserPreferenceOp(storageCtx, address);
|
|
21636
21965
|
if (deleted && walletAddress && address === walletAddress) {
|
|
21637
21966
|
patchUserSettingsSnapshot(database, walletAddress, { userPreference: null });
|
|
@@ -29605,6 +29934,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
29605
29934
|
StoredVaultMemoryModel,
|
|
29606
29935
|
StreamExpiredError,
|
|
29607
29936
|
THEME_ATTRS,
|
|
29937
|
+
TOPIC_EXTRACTION_BATCH_SIZE,
|
|
29608
29938
|
TextProcessor,
|
|
29609
29939
|
UIInteractionProvider,
|
|
29610
29940
|
WalletPoller,
|
|
@@ -29696,7 +30026,9 @@ function renderAnumaJsx(jsx3) {
|
|
|
29696
30026
|
exportElementToPdf,
|
|
29697
30027
|
exportMarkdownToPdf,
|
|
29698
30028
|
exportPublicKey,
|
|
30029
|
+
extractAndLinkEntitiesForMemoriesOp,
|
|
29699
30030
|
extractAndRetain,
|
|
30031
|
+
extractEntitiesForMemories,
|
|
29700
30032
|
extractFacts,
|
|
29701
30033
|
extractFileIds,
|
|
29702
30034
|
fileExists,
|
|
@@ -29752,6 +30084,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
29752
30084
|
getMediaOp,
|
|
29753
30085
|
getMediaTypeFromMime,
|
|
29754
30086
|
getMemoriesByEntityNamesOp,
|
|
30087
|
+
getMemoriesNeedingTopicExtractionOp,
|
|
29755
30088
|
getNotionAccessToken,
|
|
29756
30089
|
getNotionMCPUrl,
|
|
29757
30090
|
getNumberAttr,
|
|
@@ -29832,6 +30165,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
29832
30165
|
renderAnumaTree,
|
|
29833
30166
|
renderElementToCanvas,
|
|
29834
30167
|
replaceById,
|
|
30168
|
+
replaceMemoryEntitiesGuardedOp,
|
|
29835
30169
|
requestEncryptionKey,
|
|
29836
30170
|
requestKeyPair,
|
|
29837
30171
|
resolveFilePlaceholders,
|
|
@@ -29857,6 +30191,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
29857
30191
|
settingsStorageSchema,
|
|
29858
30192
|
shouldChunkMessage,
|
|
29859
30193
|
shouldRefreshTools,
|
|
30194
|
+
stampTopicsExtractedAtOp,
|
|
29860
30195
|
startGithubAuth,
|
|
29861
30196
|
startNotionAuth,
|
|
29862
30197
|
storeCalendarPendingMessage,
|