@anuma/sdk 6.21.0 → 6.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/{chunk-CIMZZ7GQ.mjs → chunk-6BULYLRY.mjs} +92 -8
- package/dist/expo/index.cjs +776 -168
- package/dist/expo/index.d.mts +152 -11
- package/dist/expo/index.d.ts +152 -11
- package/dist/expo/index.mjs +531 -20
- package/dist/{react/recall-7Q3V337H.mjs → expo/recall-CUTJWQDQ.mjs} +1 -1
- package/dist/memory/context.cjs +183 -0
- package/dist/memory/context.d.mts +936 -0
- package/dist/memory/context.d.ts +936 -0
- package/dist/memory/context.mjs +157 -0
- package/dist/react/{chunk-AVYB5IXC.mjs → chunk-GPLMMMZN.mjs} +1 -1
- package/dist/react/{chunk-JRVAUZHM.mjs → chunk-K4N52PSK.mjs} +93 -9
- package/dist/react/{consolidate-URHGJT7I.mjs → consolidate-XKS6IZFC.mjs} +2 -2
- package/dist/react/index.cjs +891 -276
- package/dist/react/index.d.mts +210 -11
- package/dist/react/index.d.ts +210 -11
- package/dist/react/index.mjs +584 -71
- package/dist/{expo/recall-FQQGE6A2.mjs → react/recall-LFHIWONV.mjs} +2 -2
- package/dist/server/{chunk-4DSDATYG.mjs → chunk-FEDRFVHD.mjs} +182 -98
- package/dist/server/index.cjs +830 -222
- package/dist/server/index.d.mts +151 -7
- package/dist/server/index.d.ts +151 -7
- package/dist/server/index.mjs +524 -13
- package/dist/server/{recall-HA4UX4BB.mjs → recall-Z2WJGXOL.mjs} +1 -1
- package/dist/telemetry/index.d.mts +7 -1
- package/dist/telemetry/index.d.ts +7 -1
- package/package.json +8 -1
- package/dist/react/{chunk-WUG6GTHO.mjs → chunk-MHZB6KIX.mjs} +8 -8
package/dist/expo/index.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
ENTITY_FANOUT,
|
|
12
12
|
ENTITY_KINDS,
|
|
13
13
|
EncryptionKeyMissingError,
|
|
14
|
+
ExtractionJob,
|
|
14
15
|
LRUCache,
|
|
15
16
|
MAX_HOPS,
|
|
16
17
|
NODE_BUDGET,
|
|
@@ -52,6 +53,7 @@ import {
|
|
|
52
53
|
decryptJsonField,
|
|
53
54
|
deleteAllVaultMemoriesForUserOp,
|
|
54
55
|
deleteConversationOp,
|
|
56
|
+
deleteMessageOp,
|
|
55
57
|
deleteVaultMemoryOp,
|
|
56
58
|
eagerEmbedContent,
|
|
57
59
|
embedAllMessages,
|
|
@@ -133,7 +135,7 @@ import {
|
|
|
133
135
|
upsertMessageOp,
|
|
134
136
|
useEncryption,
|
|
135
137
|
vaultMemoryToStored
|
|
136
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-6BULYLRY.mjs";
|
|
137
139
|
import {
|
|
138
140
|
PII_PATTERNS,
|
|
139
141
|
PiiRedactor,
|
|
@@ -5802,7 +5804,8 @@ function classifyDecay(m, now, policy) {
|
|
|
5802
5804
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
5803
5805
|
if (m.eventTimeEnd >= now) return "keep";
|
|
5804
5806
|
}
|
|
5805
|
-
|
|
5807
|
+
const observedAt = Number.isFinite(m.lastObservedAt) ? m.lastObservedAt : m.updatedAt;
|
|
5808
|
+
if (now - Math.max(m.updatedAt, observedAt) > ttlForType(m.factType, resolved)) return "archive";
|
|
5806
5809
|
return "keep";
|
|
5807
5810
|
}
|
|
5808
5811
|
|
|
@@ -6707,6 +6710,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
6707
6710
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
|
|
6708
6711
|
content: existing.content,
|
|
6709
6712
|
proofCountIncrement: 1,
|
|
6713
|
+
observationSourceIds: options.sourceChunkIds,
|
|
6710
6714
|
sourceChunkIds: mergedSourceIds,
|
|
6711
6715
|
// resurrect encodes the decay gate: ACTIVE target → { preserveUpdatedAt:
|
|
6712
6716
|
// true } (main's normal re-observation path — bump proof_count without
|
|
@@ -6950,6 +6954,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
6950
6954
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
|
|
6951
6955
|
content: existing.content,
|
|
6952
6956
|
proofCountIncrement: 1,
|
|
6957
|
+
observationSourceIds: options.sourceChunkIds,
|
|
6953
6958
|
sourceChunkIds: mergedSourceIds,
|
|
6954
6959
|
// ACTIVE target → { preserveUpdatedAt: true } (main's normal re-observation
|
|
6955
6960
|
// path); ARCHIVED (non-superseded, non-deleted) → { restore: true } and no
|
|
@@ -6999,6 +7004,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
6999
7004
|
const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
|
|
7000
7005
|
content: decision.content,
|
|
7001
7006
|
proofCountIncrement: 1,
|
|
7007
|
+
observationSourceIds: options.sourceChunkIds,
|
|
7002
7008
|
sourceChunkIds: mergedSourceIds,
|
|
7003
7009
|
embedding: JSON.stringify(newEmbedding),
|
|
7004
7010
|
embeddingModel: consolidatedModel,
|
|
@@ -7635,7 +7641,7 @@ function createAutoExtractor(options) {
|
|
|
7635
7641
|
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
7636
7642
|
}
|
|
7637
7643
|
});
|
|
7638
|
-
if (outcome !== "empty-after-retry") {
|
|
7644
|
+
if (outcome !== "empty-after-retry" && failedCount === 0) {
|
|
7639
7645
|
const advancedTo = window[window.length - 1].id;
|
|
7640
7646
|
stateFor(conversationId).watermark = advancedTo;
|
|
7641
7647
|
persistCursor(conversationId, messages, advancedTo, contiguous);
|
|
@@ -7790,6 +7796,7 @@ function toDecayInput(c) {
|
|
|
7790
7796
|
eventTimeEnd: c.eventTimeEnd,
|
|
7791
7797
|
eventTimeKind: c.eventTimeKind,
|
|
7792
7798
|
updatedAt: c.updatedAt,
|
|
7799
|
+
lastObservedAt: c.lastObservedAt,
|
|
7793
7800
|
archivedAt: c.archivedAt,
|
|
7794
7801
|
source: c.source,
|
|
7795
7802
|
trustTier: c.trustTier
|
|
@@ -7871,7 +7878,8 @@ function createDecaySweeper(options) {
|
|
|
7871
7878
|
for (const c of toArchive) {
|
|
7872
7879
|
const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
|
|
7873
7880
|
now,
|
|
7874
|
-
expectedUpdatedAt: c.updatedAt
|
|
7881
|
+
expectedUpdatedAt: c.updatedAt,
|
|
7882
|
+
expectedLastObservedAt: c.lastObservedAt ?? null
|
|
7875
7883
|
});
|
|
7876
7884
|
if (ok) archived++;
|
|
7877
7885
|
}
|
|
@@ -8116,6 +8124,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
8116
8124
|
budget: defaultBudget,
|
|
8117
8125
|
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
8118
8126
|
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
8127
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
8119
8128
|
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
8120
8129
|
...toolOptions?.excludeConversationId && {
|
|
8121
8130
|
excludeConversationId: toolOptions.excludeConversationId
|
|
@@ -8520,13 +8529,25 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
8520
8529
|
watermark,
|
|
8521
8530
|
options.reviewedMemoryIds
|
|
8522
8531
|
);
|
|
8532
|
+
const memoriesById = new Map(memories.map((memory) => [memory.uniqueId, memory]));
|
|
8533
|
+
const fallbackPriors = /* @__PURE__ */ new Map();
|
|
8534
|
+
if (previous) {
|
|
8535
|
+
for (const section of previous.sections) {
|
|
8536
|
+
if (section.sourceMemoryIds.length > 0 && section.sourceMemoryIds.every((id) => {
|
|
8537
|
+
const memory = memoriesById.get(id);
|
|
8538
|
+
return memory && !memory.isDeleted && !memory.supersededBy && scopes.includes(memory.scope) && (options.reviewedMemoryIds === void 0 || options.reviewedMemoryIds.includes(id)) && changeTime(memory) <= previous.vaultWatermark;
|
|
8539
|
+
})) {
|
|
8540
|
+
fallbackPriors.set(section.key, section);
|
|
8541
|
+
}
|
|
8542
|
+
}
|
|
8543
|
+
}
|
|
8523
8544
|
const settled = await Promise.allSettled(
|
|
8524
8545
|
facets.map(async (facet) => {
|
|
8525
8546
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
8526
8547
|
if (prior && !staleKeys.has(facet.key)) {
|
|
8527
8548
|
return prior;
|
|
8528
8549
|
}
|
|
8529
|
-
return synthesizeFacet(facet, ctx, options,
|
|
8550
|
+
return synthesizeFacet(facet, ctx, options, fallbackPriors.get(facet.key));
|
|
8530
8551
|
})
|
|
8531
8552
|
);
|
|
8532
8553
|
const sections = settled.map((r, i) => {
|
|
@@ -8539,10 +8560,7 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
8539
8560
|
error: r.reason instanceof Error ? r.reason.message : String(r.reason)
|
|
8540
8561
|
}
|
|
8541
8562
|
);
|
|
8542
|
-
return fallbackSection(
|
|
8543
|
-
facet,
|
|
8544
|
-
previous?.sections.find((s) => s.key === facet.key)
|
|
8545
|
-
);
|
|
8563
|
+
return fallbackSection(facet, fallbackPriors.get(facet.key));
|
|
8546
8564
|
});
|
|
8547
8565
|
return {
|
|
8548
8566
|
version: PROFILE_DOC_VERSION,
|
|
@@ -8730,7 +8748,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
8730
8748
|
const { text: text12, legitimateEmpty } = extractFacetText(result.structuredOutput);
|
|
8731
8749
|
if (!text12 && !legitimateEmpty && !noEvidence) {
|
|
8732
8750
|
getLogger().warn(
|
|
8733
|
-
"[memory/synthesizeProfile] facet synthesis returned degraded-empty;
|
|
8751
|
+
"[memory/synthesizeProfile] facet synthesis returned degraded-empty; using fallback section",
|
|
8734
8752
|
{ facet: facet.key, recalledCount: result.basedOn.memoryIds.length }
|
|
8735
8753
|
);
|
|
8736
8754
|
return fallbackSection(facet, prior);
|
|
@@ -9296,6 +9314,462 @@ function createMessageSourceResolver(ctx) {
|
|
|
9296
9314
|
};
|
|
9297
9315
|
}
|
|
9298
9316
|
|
|
9317
|
+
// src/lib/memory/context.ts
|
|
9318
|
+
function shouldRecallMemory(query) {
|
|
9319
|
+
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
9320
|
+
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
9321
|
+
normalized
|
|
9322
|
+
);
|
|
9323
|
+
}
|
|
9324
|
+
async function assembleMemoryContext(options) {
|
|
9325
|
+
const { query, recall: recall2, loadFacts, loadSessionRefs } = options;
|
|
9326
|
+
const memoryIds = options.memoryIds ?? options.recallOptions?.memoryIds;
|
|
9327
|
+
const ranked = shouldRecallMemory(query);
|
|
9328
|
+
const degraded = [];
|
|
9329
|
+
const guard = async (lane, run, fallback) => {
|
|
9330
|
+
try {
|
|
9331
|
+
return await run();
|
|
9332
|
+
} catch (error) {
|
|
9333
|
+
degraded.push(lane);
|
|
9334
|
+
try {
|
|
9335
|
+
options.onDegraded?.(lane, error);
|
|
9336
|
+
} catch {
|
|
9337
|
+
}
|
|
9338
|
+
return fallback;
|
|
9339
|
+
}
|
|
9340
|
+
};
|
|
9341
|
+
const scoped = memoryIds !== void 0 || options.recallOptions?.scopes !== void 0 || options.recallOptions?.folderId !== void 0;
|
|
9342
|
+
const allowed = memoryIds !== void 0 ? new Set(memoryIds) : void 0;
|
|
9343
|
+
const filters = {
|
|
9344
|
+
...options.recallOptions?.scopes && { scopes: options.recallOptions.scopes },
|
|
9345
|
+
...options.recallOptions?.folderId !== void 0 && {
|
|
9346
|
+
folderId: options.recallOptions.folderId
|
|
9347
|
+
}
|
|
9348
|
+
};
|
|
9349
|
+
const active = (m) => !m.isDeleted && !m.archivedAt && !m.supersededBy && m.trustTier !== "quarantined" && (!allowed || allowed.has(m.uniqueId));
|
|
9350
|
+
const asItem = (m, lane, score = 1) => ({
|
|
9351
|
+
id: m.uniqueId,
|
|
9352
|
+
content: m.content,
|
|
9353
|
+
score,
|
|
9354
|
+
lane,
|
|
9355
|
+
sourceIds: m.sourceChunkIds ?? []
|
|
9356
|
+
});
|
|
9357
|
+
const empty = {
|
|
9358
|
+
memories: [],
|
|
9359
|
+
usedBudget: options.recallOptions?.budget ?? "low",
|
|
9360
|
+
reranked: false,
|
|
9361
|
+
candidateCount: 0
|
|
9362
|
+
};
|
|
9363
|
+
const [facts, episodes, profile, session] = await Promise.all([
|
|
9364
|
+
ranked ? guard(
|
|
9365
|
+
"fact",
|
|
9366
|
+
() => recall2(query, { ...options.recallOptions, types: ["fact"], limit: 20, memoryIds }),
|
|
9367
|
+
empty
|
|
9368
|
+
) : empty,
|
|
9369
|
+
ranked && !scoped && options.includeEpisodes !== false ? guard(
|
|
9370
|
+
"episode",
|
|
9371
|
+
() => recall2(query, {
|
|
9372
|
+
...options.recallOptions,
|
|
9373
|
+
types: ["chunk"],
|
|
9374
|
+
limit: 4,
|
|
9375
|
+
minScore: 0.5,
|
|
9376
|
+
onDiagnostics: void 0
|
|
9377
|
+
}),
|
|
9378
|
+
empty
|
|
9379
|
+
) : empty,
|
|
9380
|
+
loadFacts ? guard(
|
|
9381
|
+
"profile",
|
|
9382
|
+
async () => {
|
|
9383
|
+
const stable = await loadFacts({
|
|
9384
|
+
...filters,
|
|
9385
|
+
memoryIds,
|
|
9386
|
+
factTypes: ["identity", "preference", "constraint", "relationship"],
|
|
9387
|
+
limit: 8
|
|
9388
|
+
});
|
|
9389
|
+
const dynamic = await loadFacts({
|
|
9390
|
+
...filters,
|
|
9391
|
+
memoryIds,
|
|
9392
|
+
factTypes: ["ongoing_context", "plan"],
|
|
9393
|
+
limit: 4
|
|
9394
|
+
});
|
|
9395
|
+
return [...stable, ...dynamic].filter(active).map((m) => asItem(m, "profile"));
|
|
9396
|
+
},
|
|
9397
|
+
[]
|
|
9398
|
+
) : [],
|
|
9399
|
+
loadFacts && loadSessionRefs ? guard(
|
|
9400
|
+
"session",
|
|
9401
|
+
async () => {
|
|
9402
|
+
const refs = (await loadSessionRefs()).filter((r) => !allowed || allowed.has(r.memoryId)).sort((a, b) => b.score - a.score).slice(0, 10);
|
|
9403
|
+
if (!refs.length) return [];
|
|
9404
|
+
const rows = await loadFacts({ ...filters, memoryIds: refs.map((r) => r.memoryId) });
|
|
9405
|
+
const byId = new Map(rows.filter(active).map((m) => [m.uniqueId, m]));
|
|
9406
|
+
return refs.flatMap((ref) => {
|
|
9407
|
+
const m = byId.get(ref.memoryId);
|
|
9408
|
+
return m ? [asItem(m, "session", ref.score)] : [];
|
|
9409
|
+
});
|
|
9410
|
+
},
|
|
9411
|
+
[]
|
|
9412
|
+
) : []
|
|
9413
|
+
]);
|
|
9414
|
+
const toItems = (result, lane) => result.memories.filter((m) => !allowed || allowed.has(m.id)).map((m) => ({
|
|
9415
|
+
id: m.id,
|
|
9416
|
+
content: m.content,
|
|
9417
|
+
score: m.score,
|
|
9418
|
+
lane,
|
|
9419
|
+
...lane === "fact" && { recalled: true },
|
|
9420
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
9421
|
+
}));
|
|
9422
|
+
const recalledFacts = toItems(facts, "fact");
|
|
9423
|
+
const recalledScores = /* @__PURE__ */ new Map();
|
|
9424
|
+
const recalledContentScores = /* @__PURE__ */ new Map();
|
|
9425
|
+
for (const item of recalledFacts) {
|
|
9426
|
+
recalledScores.set(item.id, Math.max(recalledScores.get(item.id) ?? -Infinity, item.score));
|
|
9427
|
+
const content = item.content.trim();
|
|
9428
|
+
recalledContentScores.set(
|
|
9429
|
+
content,
|
|
9430
|
+
Math.max(recalledContentScores.get(content) ?? -Infinity, item.score)
|
|
9431
|
+
);
|
|
9432
|
+
}
|
|
9433
|
+
const rankedProfile = profile.map((item) => {
|
|
9434
|
+
const score = Math.max(
|
|
9435
|
+
recalledScores.get(item.id) ?? -Infinity,
|
|
9436
|
+
recalledContentScores.get(item.content.trim()) ?? -Infinity
|
|
9437
|
+
);
|
|
9438
|
+
return score === -Infinity ? item : { ...item, score, recalled: true };
|
|
9439
|
+
});
|
|
9440
|
+
const lanes = [
|
|
9441
|
+
[rankedProfile, 2e3],
|
|
9442
|
+
[recalledFacts, 6e3],
|
|
9443
|
+
[toItems(episodes, "episode"), 3e3],
|
|
9444
|
+
[session, 1e3]
|
|
9445
|
+
];
|
|
9446
|
+
const items = [];
|
|
9447
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
9448
|
+
const seenContent = /* @__PURE__ */ new Set();
|
|
9449
|
+
let remaining = Math.max(0, options.maxChars ?? 12e3);
|
|
9450
|
+
let truncated = false;
|
|
9451
|
+
for (const [candidates, laneBudget] of lanes) {
|
|
9452
|
+
let laneRemaining = Math.min(laneBudget, remaining);
|
|
9453
|
+
for (const item of candidates) {
|
|
9454
|
+
const content = item.content?.trim();
|
|
9455
|
+
const key = `${item.lane === "episode" ? "episode" : "fact"}:${item.id}`;
|
|
9456
|
+
if (!content || seenIds.has(key) || seenContent.has(content)) continue;
|
|
9457
|
+
if (content.length > laneRemaining) {
|
|
9458
|
+
truncated = true;
|
|
9459
|
+
continue;
|
|
9460
|
+
}
|
|
9461
|
+
items.push({ ...item, content });
|
|
9462
|
+
seenIds.add(key);
|
|
9463
|
+
seenContent.add(content);
|
|
9464
|
+
remaining -= content.length;
|
|
9465
|
+
laneRemaining -= content.length;
|
|
9466
|
+
}
|
|
9467
|
+
}
|
|
9468
|
+
return { items, ranked, rankedCount: recalledFacts.length, degraded, truncated };
|
|
9469
|
+
}
|
|
9470
|
+
|
|
9471
|
+
// src/lib/memory/durableExtraction.ts
|
|
9472
|
+
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
9473
|
+
var MAX_JOBS_PER_PASS = 3;
|
|
9474
|
+
var MAX_ATTEMPTS = 3;
|
|
9475
|
+
function idsOf(job) {
|
|
9476
|
+
return JSON.parse(String(job._getRaw("message_ids")));
|
|
9477
|
+
}
|
|
9478
|
+
function seqOf(job) {
|
|
9479
|
+
const raw = job._getRaw("watermark_seq");
|
|
9480
|
+
return typeof raw === "number" && raw > 0 ? raw : void 0;
|
|
9481
|
+
}
|
|
9482
|
+
function createDurableAutoExtractor(options) {
|
|
9483
|
+
const vault = options.retainCtx.vaultCtx;
|
|
9484
|
+
const database = vault.database;
|
|
9485
|
+
const owner = vault.userId ?? vault.walletAddress;
|
|
9486
|
+
if (!owner) throw new Error("Durable extraction requires a user or wallet owner");
|
|
9487
|
+
const jobs = database.get(ExtractionJob.table);
|
|
9488
|
+
const storage = {
|
|
9489
|
+
database,
|
|
9490
|
+
messagesCollection: database.get("history"),
|
|
9491
|
+
conversationsCollection: database.get("conversations"),
|
|
9492
|
+
walletAddress: vault.walletAddress,
|
|
9493
|
+
signMessage: vault.signMessage,
|
|
9494
|
+
embeddedWalletSigner: vault.embeddedWalletSigner
|
|
9495
|
+
};
|
|
9496
|
+
const folderId = options.folderId ?? null;
|
|
9497
|
+
let disposed = false;
|
|
9498
|
+
let running = false;
|
|
9499
|
+
let wakeRequested = false;
|
|
9500
|
+
let timer;
|
|
9501
|
+
let writes = Promise.resolve();
|
|
9502
|
+
let storeFailures = 0;
|
|
9503
|
+
const attempts = /* @__PURE__ */ new Map();
|
|
9504
|
+
const reportError = (error, conversationId) => {
|
|
9505
|
+
try {
|
|
9506
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)), conversationId);
|
|
9507
|
+
} catch {
|
|
9508
|
+
}
|
|
9509
|
+
};
|
|
9510
|
+
const currentScope = () => {
|
|
9511
|
+
try {
|
|
9512
|
+
const value = typeof options.scope === "function" ? options.scope() : options.scope;
|
|
9513
|
+
return value ?? "private";
|
|
9514
|
+
} catch (error) {
|
|
9515
|
+
reportError(error);
|
|
9516
|
+
return "private";
|
|
9517
|
+
}
|
|
9518
|
+
};
|
|
9519
|
+
function schedule(delay) {
|
|
9520
|
+
if (disposed) return;
|
|
9521
|
+
if (running || timer !== void 0) {
|
|
9522
|
+
if (running) wakeRequested = true;
|
|
9523
|
+
return;
|
|
9524
|
+
}
|
|
9525
|
+
timer = setTimeout(() => {
|
|
9526
|
+
timer = void 0;
|
|
9527
|
+
void drain();
|
|
9528
|
+
}, delay);
|
|
9529
|
+
}
|
|
9530
|
+
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
9531
|
+
let watchdog;
|
|
9532
|
+
try {
|
|
9533
|
+
return await Promise.race([
|
|
9534
|
+
new Promise((resolve, reject) => {
|
|
9535
|
+
const worker = createAutoExtractor({
|
|
9536
|
+
...options,
|
|
9537
|
+
retainCtx: {
|
|
9538
|
+
...options.retainCtx,
|
|
9539
|
+
vaultCtx: {
|
|
9540
|
+
...vault,
|
|
9541
|
+
canWrite: async () => !disposed && await storage.conversationsCollection.query(Q4.where("conversation_id", conversationId), Q4.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q4.where("conversation_id", conversationId), Q4.where("id", Q4.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed
|
|
9542
|
+
}
|
|
9543
|
+
},
|
|
9544
|
+
// Never publish a private queued observation after a mode flip.
|
|
9545
|
+
scope: jobScope,
|
|
9546
|
+
folderId: jobFolderId,
|
|
9547
|
+
cursorStore: void 0,
|
|
9548
|
+
windowSize: 20,
|
|
9549
|
+
maxWindowSize: 20,
|
|
9550
|
+
onTurnComplete: resolve,
|
|
9551
|
+
onError: reject
|
|
9552
|
+
});
|
|
9553
|
+
worker.processTurn(messages, conversationId);
|
|
9554
|
+
worker.dispose();
|
|
9555
|
+
}),
|
|
9556
|
+
new Promise((_resolve, reject) => {
|
|
9557
|
+
watchdog = setTimeout(
|
|
9558
|
+
() => reject(new Error("Extraction did not settle in time; retained for retry")),
|
|
9559
|
+
options.batchTimeoutMs ?? 18e4
|
|
9560
|
+
);
|
|
9561
|
+
})
|
|
9562
|
+
]);
|
|
9563
|
+
} finally {
|
|
9564
|
+
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
9565
|
+
}
|
|
9566
|
+
}
|
|
9567
|
+
async function drain() {
|
|
9568
|
+
if (disposed || running) return;
|
|
9569
|
+
running = true;
|
|
9570
|
+
wakeRequested = false;
|
|
9571
|
+
let retry = false;
|
|
9572
|
+
let scheduleAfterSuccess = false;
|
|
9573
|
+
try {
|
|
9574
|
+
await writes;
|
|
9575
|
+
const pending = await jobs.query(Q4.where("owner_key", owner), Q4.where("message_ids", Q4.notEq("[]"))).fetch();
|
|
9576
|
+
storeFailures = 0;
|
|
9577
|
+
let processed = 0;
|
|
9578
|
+
for (const job of pending) {
|
|
9579
|
+
if (disposed) break;
|
|
9580
|
+
const attempted = attempts.get(job.id) ?? 0;
|
|
9581
|
+
if (attempted >= MAX_ATTEMPTS) continue;
|
|
9582
|
+
if (processed >= MAX_JOBS_PER_PASS) {
|
|
9583
|
+
scheduleAfterSuccess = true;
|
|
9584
|
+
break;
|
|
9585
|
+
}
|
|
9586
|
+
processed++;
|
|
9587
|
+
const conversationId = String(job._getRaw("conversation_id"));
|
|
9588
|
+
try {
|
|
9589
|
+
const conversations = await storage.conversationsCollection.query(Q4.where("conversation_id", conversationId), Q4.where("is_deleted", false)).fetchCount();
|
|
9590
|
+
if (!conversations) {
|
|
9591
|
+
await database.write(() => job.destroyPermanently());
|
|
9592
|
+
continue;
|
|
9593
|
+
}
|
|
9594
|
+
const ids = idsOf(job).slice(0, 20);
|
|
9595
|
+
const loaded = await Promise.all(ids.map((id) => getMessageOp(storage, id)));
|
|
9596
|
+
const missing = ids.filter((_id, index) => loaded[index] === null);
|
|
9597
|
+
if (missing.length) {
|
|
9598
|
+
if (attempted < MAX_ATTEMPTS - 1)
|
|
9599
|
+
throw new Error("Source messages not yet available; retained for retry");
|
|
9600
|
+
const dropped = new Set(missing);
|
|
9601
|
+
await database.write(
|
|
9602
|
+
() => job.update(
|
|
9603
|
+
(r) => r._setRaw(
|
|
9604
|
+
"message_ids",
|
|
9605
|
+
JSON.stringify(idsOf(job).filter((id) => !dropped.has(id)))
|
|
9606
|
+
)
|
|
9607
|
+
)
|
|
9608
|
+
);
|
|
9609
|
+
attempts.delete(job.id);
|
|
9610
|
+
scheduleAfterSuccess = true;
|
|
9611
|
+
reportError(
|
|
9612
|
+
new Error(
|
|
9613
|
+
`Dropped ${missing.length} unresolvable source id(s) to unblock extraction`
|
|
9614
|
+
),
|
|
9615
|
+
conversationId
|
|
9616
|
+
);
|
|
9617
|
+
continue;
|
|
9618
|
+
}
|
|
9619
|
+
if (loaded.some(
|
|
9620
|
+
(message) => message && (message.decryptionStatus || isEncrypted(message.content))
|
|
9621
|
+
)) {
|
|
9622
|
+
throw new Error("Source messages are locked; retained for retry");
|
|
9623
|
+
}
|
|
9624
|
+
const messages = loaded.flatMap(
|
|
9625
|
+
(m) => m && m.conversationId === conversationId && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
|
|
9626
|
+
);
|
|
9627
|
+
let success = messages.length === 0;
|
|
9628
|
+
if (messages.length) {
|
|
9629
|
+
const result = await extractBatch(
|
|
9630
|
+
messages,
|
|
9631
|
+
conversationId,
|
|
9632
|
+
ids,
|
|
9633
|
+
currentScope() === "private" ? "private" : String(job._getRaw("scope")),
|
|
9634
|
+
job._getRaw("folder_id") ?? null
|
|
9635
|
+
);
|
|
9636
|
+
success = result.failedCount === 0 && result.outcome !== "empty-after-retry";
|
|
9637
|
+
options.onTurnComplete?.(result);
|
|
9638
|
+
}
|
|
9639
|
+
if (!success) throw new Error("Extraction batch incomplete; retained for retry");
|
|
9640
|
+
attempts.delete(job.id);
|
|
9641
|
+
const sequences = /* @__PURE__ */ new Map();
|
|
9642
|
+
for (const message of loaded)
|
|
9643
|
+
if (message && message.messageId > 0)
|
|
9644
|
+
sequences.set(message.uniqueId, message.messageId);
|
|
9645
|
+
await database.write(async () => {
|
|
9646
|
+
const current = idsOf(job);
|
|
9647
|
+
const acknowledged = ids.filter((id) => current.includes(id));
|
|
9648
|
+
if (!acknowledged.length) return;
|
|
9649
|
+
const done = new Set(acknowledged);
|
|
9650
|
+
const remaining = current.filter((id) => !done.has(id));
|
|
9651
|
+
if (remaining.length) {
|
|
9652
|
+
await job.update(
|
|
9653
|
+
(r) => r._setRaw("message_ids", JSON.stringify([...acknowledged.slice(-2), ...remaining]))
|
|
9654
|
+
);
|
|
9655
|
+
} else await job.update((r) => r._setRaw("message_ids", "[]"));
|
|
9656
|
+
const newest = acknowledged[acknowledged.length - 1];
|
|
9657
|
+
await job.update((r) => {
|
|
9658
|
+
r._setRaw("watermark", newest);
|
|
9659
|
+
const sequence = sequences.get(newest);
|
|
9660
|
+
if (sequence !== void 0) {
|
|
9661
|
+
const prior = seqOf(job);
|
|
9662
|
+
r._setRaw(
|
|
9663
|
+
"watermark_seq",
|
|
9664
|
+
prior === void 0 ? sequence : Math.max(prior, sequence)
|
|
9665
|
+
);
|
|
9666
|
+
}
|
|
9667
|
+
});
|
|
9668
|
+
});
|
|
9669
|
+
scheduleAfterSuccess = true;
|
|
9670
|
+
} catch (error) {
|
|
9671
|
+
attempts.set(job.id, attempted + 1);
|
|
9672
|
+
retry = true;
|
|
9673
|
+
reportError(error, conversationId);
|
|
9674
|
+
}
|
|
9675
|
+
}
|
|
9676
|
+
} catch (error) {
|
|
9677
|
+
retry = ++storeFailures < 3;
|
|
9678
|
+
reportError(error);
|
|
9679
|
+
} finally {
|
|
9680
|
+
running = false;
|
|
9681
|
+
const woken = wakeRequested;
|
|
9682
|
+
wakeRequested = false;
|
|
9683
|
+
if (retry || scheduleAfterSuccess || woken)
|
|
9684
|
+
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
schedule(0);
|
|
9688
|
+
return {
|
|
9689
|
+
processTurn(messages, conversationId) {
|
|
9690
|
+
if (disposed || !conversationId || !messages.length) return false;
|
|
9691
|
+
const ids = messages.map((m) => m.id);
|
|
9692
|
+
const scope = currentScope();
|
|
9693
|
+
writes = writes.then(
|
|
9694
|
+
() => database.write(async () => {
|
|
9695
|
+
const existing = await jobs.query(Q4.where("owner_key", owner), Q4.where("conversation_id", conversationId)).fetch();
|
|
9696
|
+
const job = existing.find(
|
|
9697
|
+
(candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
|
|
9698
|
+
);
|
|
9699
|
+
const positions = new Map(ids.map((id, index) => [id, index]));
|
|
9700
|
+
const rows = await storage.messagesCollection.query(Q4.where("id", Q4.oneOf(ids))).fetch();
|
|
9701
|
+
const sequences = /* @__PURE__ */ new Map();
|
|
9702
|
+
for (const row of rows) {
|
|
9703
|
+
const sequence = Number(row._getRaw("message_id"));
|
|
9704
|
+
if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
|
|
9705
|
+
}
|
|
9706
|
+
let boundary = -1;
|
|
9707
|
+
let observedSeq = 0;
|
|
9708
|
+
const foreignSources = /* @__PURE__ */ new Set();
|
|
9709
|
+
for (const prior of existing) {
|
|
9710
|
+
const sources = [...idsOf(prior), String(prior._getRaw("watermark") ?? "")];
|
|
9711
|
+
for (const id of sources) {
|
|
9712
|
+
boundary = Math.max(boundary, positions.get(id) ?? -1);
|
|
9713
|
+
if (prior !== job) foreignSources.add(id);
|
|
9714
|
+
}
|
|
9715
|
+
observedSeq = Math.max(observedSeq, seqOf(prior) ?? 0);
|
|
9716
|
+
for (const id of idsOf(prior))
|
|
9717
|
+
observedSeq = Math.max(observedSeq, sequences.get(id) ?? 0);
|
|
9718
|
+
}
|
|
9719
|
+
if (observedSeq > 0)
|
|
9720
|
+
ids.forEach((id, index) => {
|
|
9721
|
+
const sequence = sequences.get(id);
|
|
9722
|
+
if (sequence !== void 0 && sequence <= observedSeq)
|
|
9723
|
+
boundary = Math.max(boundary, index);
|
|
9724
|
+
});
|
|
9725
|
+
if (!existing.length && options.cursorStore) {
|
|
9726
|
+
try {
|
|
9727
|
+
const cursor = options.cursorStore.get(conversationId);
|
|
9728
|
+
if (cursor) boundary = Math.max(boundary, positions.get(cursor) ?? -1);
|
|
9729
|
+
} catch (error) {
|
|
9730
|
+
reportError(error, conversationId);
|
|
9731
|
+
}
|
|
9732
|
+
}
|
|
9733
|
+
if (boundary < 0 && existing.some((prior) => idsOf(prior).length > 0 || seqOf(prior) !== void 0)) {
|
|
9734
|
+
reportError(
|
|
9735
|
+
new Error("Extraction boundary unresolved; skipped rather than re-observing"),
|
|
9736
|
+
conversationId
|
|
9737
|
+
);
|
|
9738
|
+
return;
|
|
9739
|
+
}
|
|
9740
|
+
const start = boundary >= 0 ? boundary + 1 : Math.max(0, ids.length - Math.max(1, options.windowSize ?? 6));
|
|
9741
|
+
if (start >= ids.length) return;
|
|
9742
|
+
const ownWatermark = job?._getRaw("watermark");
|
|
9743
|
+
const atOwnWatermark = !!job && boundary >= 0 && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
|
|
9744
|
+
const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
|
|
9745
|
+
const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
|
|
9746
|
+
if (!fresh.length) return;
|
|
9747
|
+
if (job) {
|
|
9748
|
+
await job.update(
|
|
9749
|
+
(r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
|
|
9750
|
+
);
|
|
9751
|
+
attempts.delete(job.id);
|
|
9752
|
+
} else {
|
|
9753
|
+
await jobs.create((r) => {
|
|
9754
|
+
r._setRaw("owner_key", owner);
|
|
9755
|
+
r._setRaw("conversation_id", conversationId);
|
|
9756
|
+
r._setRaw("scope", scope);
|
|
9757
|
+
r._setRaw("folder_id", folderId);
|
|
9758
|
+
r._setRaw("message_ids", JSON.stringify([...new Set(fresh)]));
|
|
9759
|
+
});
|
|
9760
|
+
}
|
|
9761
|
+
})
|
|
9762
|
+
).then(() => schedule(options.debounceMs ?? 2e4)).catch((error) => reportError(error, conversationId));
|
|
9763
|
+
return true;
|
|
9764
|
+
},
|
|
9765
|
+
isProcessing: () => running,
|
|
9766
|
+
dispose() {
|
|
9767
|
+
disposed = true;
|
|
9768
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
9769
|
+
}
|
|
9770
|
+
};
|
|
9771
|
+
}
|
|
9772
|
+
|
|
9299
9773
|
// src/lib/memoryEngine/quantization.ts
|
|
9300
9774
|
var INT8_MAX = 127;
|
|
9301
9775
|
function quantizeEmbedding(v) {
|
|
@@ -12697,10 +13171,25 @@ __decorateClass([
|
|
|
12697
13171
|
], VaultFolder.prototype, "context", 2);
|
|
12698
13172
|
|
|
12699
13173
|
// src/lib/db/schema.ts
|
|
12700
|
-
var SDK_SCHEMA_VERSION =
|
|
13174
|
+
var SDK_SCHEMA_VERSION = 46;
|
|
12701
13175
|
var sdkSchema = appSchema2({
|
|
12702
13176
|
version: SDK_SCHEMA_VERSION,
|
|
12703
13177
|
tables: [
|
|
13178
|
+
tableSchema2({
|
|
13179
|
+
name: "memory_extraction_jobs",
|
|
13180
|
+
columns: [
|
|
13181
|
+
{ name: "owner_key", type: "string", isIndexed: true },
|
|
13182
|
+
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
13183
|
+
{ name: "scope", type: "string" },
|
|
13184
|
+
{ name: "message_ids", type: "string" },
|
|
13185
|
+
{ name: "watermark", type: "string", isOptional: true },
|
|
13186
|
+
// Deletion-proof anchor: history.message_id of the newest acknowledged
|
|
13187
|
+
// source. `watermark` alone is an id, and deleting that message erased
|
|
13188
|
+
// the anchor — see the column note in extractionJobs/models.ts.
|
|
13189
|
+
{ name: "watermark_seq", type: "number", isOptional: true },
|
|
13190
|
+
{ name: "folder_id", type: "string", isOptional: true }
|
|
13191
|
+
]
|
|
13192
|
+
}),
|
|
12704
13193
|
// Chat storage tables
|
|
12705
13194
|
tableSchema2({
|
|
12706
13195
|
name: "history",
|
|
@@ -13705,10 +14194,28 @@ var sdkMigrations = schemaMigrations2({
|
|
|
13705
14194
|
columns: [{ name: "media", type: "string", isOptional: true }]
|
|
13706
14195
|
})
|
|
13707
14196
|
]
|
|
14197
|
+
},
|
|
14198
|
+
{
|
|
14199
|
+
toVersion: 46,
|
|
14200
|
+
steps: [
|
|
14201
|
+
createTable({
|
|
14202
|
+
name: "memory_extraction_jobs",
|
|
14203
|
+
columns: [
|
|
14204
|
+
{ name: "owner_key", type: "string", isIndexed: true },
|
|
14205
|
+
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
14206
|
+
{ name: "scope", type: "string" },
|
|
14207
|
+
{ name: "message_ids", type: "string" },
|
|
14208
|
+
{ name: "watermark", type: "string", isOptional: true },
|
|
14209
|
+
{ name: "watermark_seq", type: "number", isOptional: true },
|
|
14210
|
+
{ name: "folder_id", type: "string", isOptional: true }
|
|
14211
|
+
]
|
|
14212
|
+
})
|
|
14213
|
+
]
|
|
13708
14214
|
}
|
|
13709
14215
|
]
|
|
13710
14216
|
});
|
|
13711
14217
|
var sdkModelClasses = [
|
|
14218
|
+
ExtractionJob,
|
|
13712
14219
|
Message,
|
|
13713
14220
|
Conversation,
|
|
13714
14221
|
ConversationSummary,
|
|
@@ -13886,7 +14393,7 @@ var DatabaseManager = class {
|
|
|
13886
14393
|
};
|
|
13887
14394
|
|
|
13888
14395
|
// src/lib/db/conversationMemory/operations.ts
|
|
13889
|
-
import { Q as
|
|
14396
|
+
import { Q as Q5 } from "@nozbe/watermelondb";
|
|
13890
14397
|
var MAX_PER_CONVERSATION = 200;
|
|
13891
14398
|
function conversationMemoryToStored(row) {
|
|
13892
14399
|
return {
|
|
@@ -13901,7 +14408,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
13901
14408
|
if (!conversationId || items.length === 0) return;
|
|
13902
14409
|
const now = Date.now();
|
|
13903
14410
|
await ctx.database.write(async () => {
|
|
13904
|
-
const existing = await ctx.conversationMemoryCollection.query(
|
|
14411
|
+
const existing = await ctx.conversationMemoryCollection.query(Q5.where("conversation_id", conversationId), Q5.sortBy("created_at", Q5.asc)).fetch();
|
|
13905
14412
|
const seen = new Set(existing.map((r) => r.memoryId));
|
|
13906
14413
|
const batchSeen = /* @__PURE__ */ new Set();
|
|
13907
14414
|
const deduped = [];
|
|
@@ -13936,20 +14443,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
|
|
|
13936
14443
|
}
|
|
13937
14444
|
async function getConversationMemoriesOp(ctx, conversationId) {
|
|
13938
14445
|
if (!conversationId) return [];
|
|
13939
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
14446
|
+
const rows = await ctx.conversationMemoryCollection.query(Q5.where("conversation_id", conversationId), Q5.sortBy("created_at", Q5.asc)).fetch();
|
|
13940
14447
|
return rows.map(conversationMemoryToStored);
|
|
13941
14448
|
}
|
|
13942
14449
|
async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
13943
14450
|
if (!conversationId) return;
|
|
13944
14451
|
await ctx.database.write(async () => {
|
|
13945
|
-
const rows = await ctx.conversationMemoryCollection.query(
|
|
14452
|
+
const rows = await ctx.conversationMemoryCollection.query(Q5.where("conversation_id", conversationId)).fetch();
|
|
13946
14453
|
if (rows.length === 0) return;
|
|
13947
14454
|
await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
|
|
13948
14455
|
});
|
|
13949
14456
|
}
|
|
13950
14457
|
|
|
13951
14458
|
// src/lib/db/vaultFolders/operations.ts
|
|
13952
|
-
import { Q as
|
|
14459
|
+
import { Q as Q6 } from "@nozbe/watermelondb";
|
|
13953
14460
|
function folderToStored(folder) {
|
|
13954
14461
|
return {
|
|
13955
14462
|
uniqueId: folder.id,
|
|
@@ -13974,7 +14481,7 @@ async function createVaultFolderOp(ctx, opts) {
|
|
|
13974
14481
|
return folderToStored(created);
|
|
13975
14482
|
}
|
|
13976
14483
|
async function getAllVaultFoldersOp(ctx) {
|
|
13977
|
-
const results = await ctx.vaultFolderCollection.query(
|
|
14484
|
+
const results = await ctx.vaultFolderCollection.query(Q6.where("is_deleted", false), Q6.sortBy("created_at", Q6.desc)).fetch();
|
|
13978
14485
|
return results.map(folderToStored);
|
|
13979
14486
|
}
|
|
13980
14487
|
async function updateVaultFolderOp(ctx, id, opts) {
|
|
@@ -13983,7 +14490,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
|
|
|
13983
14490
|
if (record.isDeleted) return null;
|
|
13984
14491
|
const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
|
|
13985
14492
|
const updated = await ctx.database.write(async () => {
|
|
13986
|
-
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(
|
|
14493
|
+
const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q6.where("folder_id", id), Q6.where("is_deleted", false)).fetch() : [];
|
|
13987
14494
|
const updates = [];
|
|
13988
14495
|
updates.push(
|
|
13989
14496
|
record.prepareUpdate((r) => {
|
|
@@ -14011,7 +14518,7 @@ async function deleteVaultFolderOp(ctx, id) {
|
|
|
14011
14518
|
const record = await ctx.vaultFolderCollection.find(id);
|
|
14012
14519
|
if (record.isDeleted) return false;
|
|
14013
14520
|
await ctx.database.write(async () => {
|
|
14014
|
-
const memories = await ctx.vaultMemoryCollection.query(
|
|
14521
|
+
const memories = await ctx.vaultMemoryCollection.query(Q6.where("folder_id", id), Q6.where("is_deleted", false)).fetch();
|
|
14015
14522
|
const preparedMemories = memories.map(
|
|
14016
14523
|
(memory) => memory.prepareUpdate((r) => {
|
|
14017
14524
|
r._setRaw("folder_id", null);
|
|
@@ -14080,7 +14587,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
|
|
|
14080
14587
|
}
|
|
14081
14588
|
}
|
|
14082
14589
|
async function getVaultFolderMemoryCountOp(ctx, folderId) {
|
|
14083
|
-
return await ctx.vaultMemoryCollection.query(
|
|
14590
|
+
return await ctx.vaultMemoryCollection.query(Q6.where("folder_id", folderId), Q6.where("is_deleted", false)).fetchCount();
|
|
14084
14591
|
}
|
|
14085
14592
|
|
|
14086
14593
|
// src/lib/db/vaultFolders/defaults.ts
|
|
@@ -15088,6 +15595,7 @@ export {
|
|
|
15088
15595
|
WalletPoller,
|
|
15089
15596
|
addConversationMemoriesOp,
|
|
15090
15597
|
archiveVaultMemoryOp,
|
|
15598
|
+
assembleMemoryContext,
|
|
15091
15599
|
backfillMemoryTopicsOp,
|
|
15092
15600
|
buildNotionAuthUrl,
|
|
15093
15601
|
capHopsForDensity,
|
|
@@ -15120,6 +15628,7 @@ export {
|
|
|
15120
15628
|
createChunkVectorCache,
|
|
15121
15629
|
createCryptoPricePreProcessor,
|
|
15122
15630
|
createDecaySweeper,
|
|
15631
|
+
createDurableAutoExtractor,
|
|
15123
15632
|
createLlmDecayClassifier,
|
|
15124
15633
|
createLlmNeighborRefiner,
|
|
15125
15634
|
createMemoryEngineTool,
|
|
@@ -15140,6 +15649,7 @@ export {
|
|
|
15140
15649
|
decodeChunkVector,
|
|
15141
15650
|
decryptConversationTitle,
|
|
15142
15651
|
deleteAllVaultMemoriesForUserOp,
|
|
15652
|
+
deleteMessageOp,
|
|
15143
15653
|
deleteVaultFolderOp,
|
|
15144
15654
|
deleteVaultMemoryOp,
|
|
15145
15655
|
dequantizeEmbedding,
|
|
@@ -15212,6 +15722,7 @@ export {
|
|
|
15212
15722
|
setLogger,
|
|
15213
15723
|
setMemoryVisibilityOp,
|
|
15214
15724
|
shouldChunkMessage,
|
|
15725
|
+
shouldRecallMemory,
|
|
15215
15726
|
stampTopicsExtractedAtOp,
|
|
15216
15727
|
streamCancelPath,
|
|
15217
15728
|
streamReplayPath,
|