@anuma/sdk 10.5.1 → 10.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +105 -58
- package/dist/expo/index.d.mts +7 -0
- package/dist/expo/index.d.ts +7 -0
- package/dist/expo/index.mjs +105 -58
- package/dist/react/index.cjs +131 -58
- package/dist/react/index.d.mts +13 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.mjs +131 -58
- package/dist/server/index.cjs +67 -58
- package/dist/server/index.d.mts +7 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.mjs +67 -58
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -4879,6 +4879,63 @@ async function chunkRowSource(ctx, filter) {
|
|
|
4879
4879
|
return fullScanChunkRowSource(ctx, filter);
|
|
4880
4880
|
}
|
|
4881
4881
|
}
|
|
4882
|
+
async function readChunkVectorRow(ctx, row, onUnreadable) {
|
|
4883
|
+
const version = Number(row.updated_at) || 0;
|
|
4884
|
+
const chunks3 = await readRawJsonField(row, "chunks", ctx.walletAddress);
|
|
4885
|
+
if (chunks3 && chunks3.length > 0) {
|
|
4886
|
+
return {
|
|
4887
|
+
entry: {
|
|
4888
|
+
version,
|
|
4889
|
+
chunks: chunks3.map((chunk) => decodeChunkVector(chunk.vector, onUnreadable))
|
|
4890
|
+
},
|
|
4891
|
+
chunks: chunks3
|
|
4892
|
+
};
|
|
4893
|
+
}
|
|
4894
|
+
const messageVector = await readRawJsonField(row, "vector", ctx.walletAddress);
|
|
4895
|
+
if (!messageVector || messageVector.length === 0) return null;
|
|
4896
|
+
return { entry: { version, chunks: [], fallback: Float32Array.from(messageVector) }, chunks: [] };
|
|
4897
|
+
}
|
|
4898
|
+
async function warmChunkVectorCacheOp(ctx, options) {
|
|
4899
|
+
const { chunkCache, embeddingModel, limit, signal } = options;
|
|
4900
|
+
const source = await chunkRowSource(ctx, {});
|
|
4901
|
+
const yieldIfDue = createTimeSliceYielder(CHUNK_SCAN_YIELD_BUDGET_MS);
|
|
4902
|
+
let keys = source.keys.filter(
|
|
4903
|
+
(key3) => !embeddingModel || key3.embeddingModel === null || key3.embeddingModel === embeddingModel
|
|
4904
|
+
);
|
|
4905
|
+
if (limit !== void 0 && keys.length > limit) {
|
|
4906
|
+
keys = keys.sort((a, b) => b.version - a.version).slice(0, limit);
|
|
4907
|
+
}
|
|
4908
|
+
const missIds = [];
|
|
4909
|
+
for (const key3 of keys) {
|
|
4910
|
+
await yieldIfDue();
|
|
4911
|
+
if (chunkCache.get(key3.id)?.version !== key3.version) missIds.push(key3.id);
|
|
4912
|
+
}
|
|
4913
|
+
let warmed = 0;
|
|
4914
|
+
let unreadableVectors = 0;
|
|
4915
|
+
for await (const row of loadVectorRowsInBatches(source, missIds)) {
|
|
4916
|
+
await yieldIfDue();
|
|
4917
|
+
const read = await readChunkVectorRow(ctx, row, () => {
|
|
4918
|
+
unreadableVectors++;
|
|
4919
|
+
});
|
|
4920
|
+
if (signal?.aborted) break;
|
|
4921
|
+
if (!read) continue;
|
|
4922
|
+
chunkCache.set(row.id, read.entry);
|
|
4923
|
+
warmed++;
|
|
4924
|
+
}
|
|
4925
|
+
warnUnreadableChunkVectors("warmChunkVectorCacheOp", unreadableVectors);
|
|
4926
|
+
return warmed;
|
|
4927
|
+
}
|
|
4928
|
+
async function* loadVectorRowsInBatches(source, ids) {
|
|
4929
|
+
for (let offset = 0; offset < ids.length; offset += CHUNK_VECTOR_BATCH_SIZE) {
|
|
4930
|
+
yield* await source.loadVectorRows(ids.slice(offset, offset + CHUNK_VECTOR_BATCH_SIZE));
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4933
|
+
function warnUnreadableChunkVectors(operation, count2) {
|
|
4934
|
+
if (count2 === 0) return;
|
|
4935
|
+
getLogger().warn(
|
|
4936
|
+
`${operation}: could not read ${count2} chunk vectors and left them out of ranking \u2014 the stored value is corrupt, so those chunks stay unsearchable until the message is re-embedded via chunkAndEmbedAllMessages`
|
|
4937
|
+
);
|
|
4938
|
+
}
|
|
4882
4939
|
async function searchChunksOp(ctx, queryVector, options) {
|
|
4883
4940
|
const {
|
|
4884
4941
|
limit = 10,
|
|
@@ -4947,45 +5004,39 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4947
5004
|
for (const row of rows) {
|
|
4948
5005
|
await yieldIfDue();
|
|
4949
5006
|
const id2 = row.id;
|
|
4950
|
-
const version = Number(row.updated_at) || 0;
|
|
4951
5007
|
const order = orderById.get(id2) ?? Number.MAX_SAFE_INTEGER;
|
|
4952
|
-
const
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
similarity,
|
|
4970
|
-
chunkTextSource: { kind: "chunk", chunk: chunks3[ci], siblings: chunks3 }
|
|
4971
|
-
});
|
|
4972
|
-
}
|
|
5008
|
+
const read = await readChunkVectorRow(ctx, row, () => {
|
|
5009
|
+
unreadableVectors++;
|
|
5010
|
+
});
|
|
5011
|
+
if (!read) continue;
|
|
5012
|
+
const { entry, chunks: chunks3 } = read;
|
|
5013
|
+
const { version } = entry;
|
|
5014
|
+
chunkCache?.set(id2, entry);
|
|
5015
|
+
if (entry.fallback) {
|
|
5016
|
+
const similarity = cosineSimilarity(queryVector, entry.fallback);
|
|
5017
|
+
if (similarity >= minSimilarity) {
|
|
5018
|
+
candidates.push({
|
|
5019
|
+
id: id2,
|
|
5020
|
+
version,
|
|
5021
|
+
order,
|
|
5022
|
+
similarity,
|
|
5023
|
+
chunkTextSource: { kind: "message" }
|
|
5024
|
+
});
|
|
4973
5025
|
}
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
}
|
|
5026
|
+
continue;
|
|
5027
|
+
}
|
|
5028
|
+
for (let ci = 0; ci < chunks3.length; ci++) {
|
|
5029
|
+
const vec = entry.chunks[ci];
|
|
5030
|
+
if (vec.length === 0) continue;
|
|
5031
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
5032
|
+
if (similarity >= minSimilarity) {
|
|
5033
|
+
candidates.push({
|
|
5034
|
+
id: id2,
|
|
5035
|
+
version,
|
|
5036
|
+
order,
|
|
5037
|
+
similarity,
|
|
5038
|
+
chunkTextSource: { kind: "chunk", chunk: chunks3[ci], siblings: chunks3 }
|
|
5039
|
+
});
|
|
4989
5040
|
}
|
|
4990
5041
|
}
|
|
4991
5042
|
}
|
|
@@ -4996,11 +5047,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4996
5047
|
`searchChunksOp: skipped ${staleSkipped} messages whose embedding model differs from the current model (${embeddingModel}) \u2014 re-embed via chunkAndEmbedAllMessages`
|
|
4997
5048
|
);
|
|
4998
5049
|
}
|
|
4999
|
-
|
|
5000
|
-
getLogger().warn(
|
|
5001
|
-
`searchChunksOp: could not read ${unreadableVectors} chunk vectors and left them out of ranking \u2014 the stored value is corrupt, so those chunks stay unsearchable until the message is re-embedded via chunkAndEmbedAllMessages`
|
|
5002
|
-
);
|
|
5003
|
-
}
|
|
5050
|
+
warnUnreadableChunkVectors("searchChunksOp", unreadableVectors);
|
|
5004
5051
|
const topK = candidates.sort((a, b) => b.similarity - a.similarity || a.order - b.order).slice(0, limit);
|
|
5005
5052
|
const topIds = Array.from(new Set(topK.map((c) => c.id)));
|
|
5006
5053
|
const fullRows = await source.loadFullRows(topIds);
|
|
@@ -21405,12 +21452,16 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
21405
21452
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
21406
21453
|
const uncachedTexts = [];
|
|
21407
21454
|
const uncachedIndices = [];
|
|
21455
|
+
const resolvedVectors = /* @__PURE__ */ new Map();
|
|
21408
21456
|
let staleReembedCount = 0;
|
|
21409
21457
|
for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
|
|
21410
21458
|
const content = memories[i].content;
|
|
21411
21459
|
const memoryId = memories[i].uniqueId;
|
|
21412
21460
|
const cached = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
|
|
21413
|
-
if (cached && cached.length === queryEmbedding.length)
|
|
21461
|
+
if (cached && cached.length === queryEmbedding.length) {
|
|
21462
|
+
resolvedVectors.set(memoryId, cached);
|
|
21463
|
+
continue;
|
|
21464
|
+
}
|
|
21414
21465
|
if (cached) cache.delete(memoryId);
|
|
21415
21466
|
const storedModel = memories[i].embeddingModel;
|
|
21416
21467
|
const modelCompatible = (storedModel ?? currentModel) === currentModel;
|
|
@@ -21418,13 +21469,9 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
21418
21469
|
try {
|
|
21419
21470
|
const parsed = JSON.parse(memories[i].embedding);
|
|
21420
21471
|
if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
|
|
21421
|
-
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
Float32Array.from(parsed),
|
|
21425
|
-
memories[i].updatedAt,
|
|
21426
|
-
content
|
|
21427
|
-
);
|
|
21472
|
+
const vector2 = Float32Array.from(parsed);
|
|
21473
|
+
resolvedVectors.set(memoryId, vector2);
|
|
21474
|
+
cacheRowVector(cache, memoryId, vector2, memories[i].updatedAt, content);
|
|
21428
21475
|
continue;
|
|
21429
21476
|
}
|
|
21430
21477
|
} catch {
|
|
@@ -21457,20 +21504,17 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
21457
21504
|
}
|
|
21458
21505
|
if (newEmbeddings) {
|
|
21459
21506
|
for (let j = 0; j < uncachedTexts.length; j++) {
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21463
|
-
|
|
21464
|
-
memories[uncachedIndices[j]].updatedAt,
|
|
21465
|
-
memories[uncachedIndices[j]].content
|
|
21466
|
-
);
|
|
21507
|
+
const memory = memories[uncachedIndices[j]];
|
|
21508
|
+
const vector2 = Float32Array.from(newEmbeddings[j]);
|
|
21509
|
+
resolvedVectors.set(memory.uniqueId, vector2);
|
|
21510
|
+
cacheRowVector(cache, memory.uniqueId, vector2, memory.updatedAt, memory.content);
|
|
21467
21511
|
}
|
|
21468
21512
|
}
|
|
21469
21513
|
}
|
|
21470
21514
|
embeddedItems = memories.map((m) => ({
|
|
21471
21515
|
id: m.uniqueId,
|
|
21472
21516
|
content: m.content,
|
|
21473
|
-
embedding:
|
|
21517
|
+
embedding: resolvedVectors.get(m.uniqueId) ?? [],
|
|
21474
21518
|
createdAt: m.createdAt,
|
|
21475
21519
|
updatedAt: m.updatedAt,
|
|
21476
21520
|
proofCount: m.proofCount,
|
|
@@ -29910,6 +29954,9 @@ var WatermelonChatStorageAdapter = class {
|
|
|
29910
29954
|
searchChunks(queryVector, options) {
|
|
29911
29955
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
29912
29956
|
}
|
|
29957
|
+
warmChunkCache(options) {
|
|
29958
|
+
return warmChunkVectorCacheOp(this.ctx, options);
|
|
29959
|
+
}
|
|
29913
29960
|
getSummary(conversationId) {
|
|
29914
29961
|
return getConversationSummaryOp(
|
|
29915
29962
|
createSummaryContext(this.ctx.database, this.ctx),
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -4436,6 +4436,13 @@ interface ChatBackend extends ChatStorageAdapter {
|
|
|
4436
4436
|
uniqueId: string;
|
|
4437
4437
|
}): Promise<StoredMessage>;
|
|
4438
4438
|
searchChunks(queryVector: number[], options?: ChatChunkSearchOptions): Promise<ChunkSearchResult[]>;
|
|
4439
|
+
/** Fills a chunk vector cache ahead of the first search, for backends that score on the device. */
|
|
4440
|
+
warmChunkCache?(options: {
|
|
4441
|
+
chunkCache: ChunkVectorCache;
|
|
4442
|
+
embeddingModel?: string;
|
|
4443
|
+
limit?: number;
|
|
4444
|
+
signal?: AbortSignal;
|
|
4445
|
+
}): Promise<number>;
|
|
4439
4446
|
getSummary(conversationId: string): Promise<StoredConversationSummary | null>;
|
|
4440
4447
|
upsertSummary(conversationId: string, summary: string, summarizedUpTo: string, tokenCount: number): Promise<StoredConversationSummary>;
|
|
4441
4448
|
deleteSummary(conversationId: string): Promise<void>;
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -4436,6 +4436,13 @@ interface ChatBackend extends ChatStorageAdapter {
|
|
|
4436
4436
|
uniqueId: string;
|
|
4437
4437
|
}): Promise<StoredMessage>;
|
|
4438
4438
|
searchChunks(queryVector: number[], options?: ChatChunkSearchOptions): Promise<ChunkSearchResult[]>;
|
|
4439
|
+
/** Fills a chunk vector cache ahead of the first search, for backends that score on the device. */
|
|
4440
|
+
warmChunkCache?(options: {
|
|
4441
|
+
chunkCache: ChunkVectorCache;
|
|
4442
|
+
embeddingModel?: string;
|
|
4443
|
+
limit?: number;
|
|
4444
|
+
signal?: AbortSignal;
|
|
4445
|
+
}): Promise<number>;
|
|
4439
4446
|
getSummary(conversationId: string): Promise<StoredConversationSummary | null>;
|
|
4440
4447
|
upsertSummary(conversationId: string, summary: string, summarizedUpTo: string, tokenCount: number): Promise<StoredConversationSummary>;
|
|
4441
4448
|
deleteSummary(conversationId: string): Promise<void>;
|
package/dist/expo/index.mjs
CHANGED
|
@@ -3234,6 +3234,63 @@ async function chunkRowSource(ctx, filter) {
|
|
|
3234
3234
|
return fullScanChunkRowSource(ctx, filter);
|
|
3235
3235
|
}
|
|
3236
3236
|
}
|
|
3237
|
+
async function readChunkVectorRow(ctx, row, onUnreadable) {
|
|
3238
|
+
const version = Number(row.updated_at) || 0;
|
|
3239
|
+
const chunks3 = await readRawJsonField(row, "chunks", ctx.walletAddress);
|
|
3240
|
+
if (chunks3 && chunks3.length > 0) {
|
|
3241
|
+
return {
|
|
3242
|
+
entry: {
|
|
3243
|
+
version,
|
|
3244
|
+
chunks: chunks3.map((chunk) => decodeChunkVector(chunk.vector, onUnreadable))
|
|
3245
|
+
},
|
|
3246
|
+
chunks: chunks3
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
const messageVector = await readRawJsonField(row, "vector", ctx.walletAddress);
|
|
3250
|
+
if (!messageVector || messageVector.length === 0) return null;
|
|
3251
|
+
return { entry: { version, chunks: [], fallback: Float32Array.from(messageVector) }, chunks: [] };
|
|
3252
|
+
}
|
|
3253
|
+
async function warmChunkVectorCacheOp(ctx, options) {
|
|
3254
|
+
const { chunkCache, embeddingModel, limit, signal } = options;
|
|
3255
|
+
const source = await chunkRowSource(ctx, {});
|
|
3256
|
+
const yieldIfDue = createTimeSliceYielder(CHUNK_SCAN_YIELD_BUDGET_MS);
|
|
3257
|
+
let keys = source.keys.filter(
|
|
3258
|
+
(key3) => !embeddingModel || key3.embeddingModel === null || key3.embeddingModel === embeddingModel
|
|
3259
|
+
);
|
|
3260
|
+
if (limit !== void 0 && keys.length > limit) {
|
|
3261
|
+
keys = keys.sort((a, b) => b.version - a.version).slice(0, limit);
|
|
3262
|
+
}
|
|
3263
|
+
const missIds = [];
|
|
3264
|
+
for (const key3 of keys) {
|
|
3265
|
+
await yieldIfDue();
|
|
3266
|
+
if (chunkCache.get(key3.id)?.version !== key3.version) missIds.push(key3.id);
|
|
3267
|
+
}
|
|
3268
|
+
let warmed = 0;
|
|
3269
|
+
let unreadableVectors = 0;
|
|
3270
|
+
for await (const row of loadVectorRowsInBatches(source, missIds)) {
|
|
3271
|
+
await yieldIfDue();
|
|
3272
|
+
const read = await readChunkVectorRow(ctx, row, () => {
|
|
3273
|
+
unreadableVectors++;
|
|
3274
|
+
});
|
|
3275
|
+
if (signal?.aborted) break;
|
|
3276
|
+
if (!read) continue;
|
|
3277
|
+
chunkCache.set(row.id, read.entry);
|
|
3278
|
+
warmed++;
|
|
3279
|
+
}
|
|
3280
|
+
warnUnreadableChunkVectors("warmChunkVectorCacheOp", unreadableVectors);
|
|
3281
|
+
return warmed;
|
|
3282
|
+
}
|
|
3283
|
+
async function* loadVectorRowsInBatches(source, ids) {
|
|
3284
|
+
for (let offset = 0; offset < ids.length; offset += CHUNK_VECTOR_BATCH_SIZE) {
|
|
3285
|
+
yield* await source.loadVectorRows(ids.slice(offset, offset + CHUNK_VECTOR_BATCH_SIZE));
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
function warnUnreadableChunkVectors(operation, count2) {
|
|
3289
|
+
if (count2 === 0) return;
|
|
3290
|
+
getLogger().warn(
|
|
3291
|
+
`${operation}: could not read ${count2} chunk vectors and left them out of ranking \u2014 the stored value is corrupt, so those chunks stay unsearchable until the message is re-embedded via chunkAndEmbedAllMessages`
|
|
3292
|
+
);
|
|
3293
|
+
}
|
|
3237
3294
|
async function searchChunksOp(ctx, queryVector, options) {
|
|
3238
3295
|
const {
|
|
3239
3296
|
limit = 10,
|
|
@@ -3302,45 +3359,39 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
3302
3359
|
for (const row of rows) {
|
|
3303
3360
|
await yieldIfDue();
|
|
3304
3361
|
const id2 = row.id;
|
|
3305
|
-
const version = Number(row.updated_at) || 0;
|
|
3306
3362
|
const order = orderById.get(id2) ?? Number.MAX_SAFE_INTEGER;
|
|
3307
|
-
const
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
similarity,
|
|
3325
|
-
chunkTextSource: { kind: "chunk", chunk: chunks3[ci], siblings: chunks3 }
|
|
3326
|
-
});
|
|
3327
|
-
}
|
|
3363
|
+
const read = await readChunkVectorRow(ctx, row, () => {
|
|
3364
|
+
unreadableVectors++;
|
|
3365
|
+
});
|
|
3366
|
+
if (!read) continue;
|
|
3367
|
+
const { entry, chunks: chunks3 } = read;
|
|
3368
|
+
const { version } = entry;
|
|
3369
|
+
chunkCache?.set(id2, entry);
|
|
3370
|
+
if (entry.fallback) {
|
|
3371
|
+
const similarity = cosineSimilarity(queryVector, entry.fallback);
|
|
3372
|
+
if (similarity >= minSimilarity) {
|
|
3373
|
+
candidates.push({
|
|
3374
|
+
id: id2,
|
|
3375
|
+
version,
|
|
3376
|
+
order,
|
|
3377
|
+
similarity,
|
|
3378
|
+
chunkTextSource: { kind: "message" }
|
|
3379
|
+
});
|
|
3328
3380
|
}
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
}
|
|
3381
|
+
continue;
|
|
3382
|
+
}
|
|
3383
|
+
for (let ci = 0; ci < chunks3.length; ci++) {
|
|
3384
|
+
const vec = entry.chunks[ci];
|
|
3385
|
+
if (vec.length === 0) continue;
|
|
3386
|
+
const similarity = cosineSimilarity(queryVector, vec);
|
|
3387
|
+
if (similarity >= minSimilarity) {
|
|
3388
|
+
candidates.push({
|
|
3389
|
+
id: id2,
|
|
3390
|
+
version,
|
|
3391
|
+
order,
|
|
3392
|
+
similarity,
|
|
3393
|
+
chunkTextSource: { kind: "chunk", chunk: chunks3[ci], siblings: chunks3 }
|
|
3394
|
+
});
|
|
3344
3395
|
}
|
|
3345
3396
|
}
|
|
3346
3397
|
}
|
|
@@ -3351,11 +3402,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
3351
3402
|
`searchChunksOp: skipped ${staleSkipped} messages whose embedding model differs from the current model (${embeddingModel}) \u2014 re-embed via chunkAndEmbedAllMessages`
|
|
3352
3403
|
);
|
|
3353
3404
|
}
|
|
3354
|
-
|
|
3355
|
-
getLogger().warn(
|
|
3356
|
-
`searchChunksOp: could not read ${unreadableVectors} chunk vectors and left them out of ranking \u2014 the stored value is corrupt, so those chunks stay unsearchable until the message is re-embedded via chunkAndEmbedAllMessages`
|
|
3357
|
-
);
|
|
3358
|
-
}
|
|
3405
|
+
warnUnreadableChunkVectors("searchChunksOp", unreadableVectors);
|
|
3359
3406
|
const topK = candidates.sort((a, b) => b.similarity - a.similarity || a.order - b.order).slice(0, limit);
|
|
3360
3407
|
const topIds = Array.from(new Set(topK.map((c) => c.id)));
|
|
3361
3408
|
const fullRows = await source.loadFullRows(topIds);
|
|
@@ -19712,12 +19759,16 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
19712
19759
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
19713
19760
|
const uncachedTexts = [];
|
|
19714
19761
|
const uncachedIndices = [];
|
|
19762
|
+
const resolvedVectors = /* @__PURE__ */ new Map();
|
|
19715
19763
|
let staleReembedCount = 0;
|
|
19716
19764
|
for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
|
|
19717
19765
|
const content = memories[i].content;
|
|
19718
19766
|
const memoryId = memories[i].uniqueId;
|
|
19719
19767
|
const cached = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
|
|
19720
|
-
if (cached && cached.length === queryEmbedding.length)
|
|
19768
|
+
if (cached && cached.length === queryEmbedding.length) {
|
|
19769
|
+
resolvedVectors.set(memoryId, cached);
|
|
19770
|
+
continue;
|
|
19771
|
+
}
|
|
19721
19772
|
if (cached) cache.delete(memoryId);
|
|
19722
19773
|
const storedModel = memories[i].embeddingModel;
|
|
19723
19774
|
const modelCompatible = (storedModel ?? currentModel) === currentModel;
|
|
@@ -19725,13 +19776,9 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
19725
19776
|
try {
|
|
19726
19777
|
const parsed = JSON.parse(memories[i].embedding);
|
|
19727
19778
|
if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
|
|
19728
|
-
|
|
19729
|
-
|
|
19730
|
-
|
|
19731
|
-
Float32Array.from(parsed),
|
|
19732
|
-
memories[i].updatedAt,
|
|
19733
|
-
content
|
|
19734
|
-
);
|
|
19779
|
+
const vector2 = Float32Array.from(parsed);
|
|
19780
|
+
resolvedVectors.set(memoryId, vector2);
|
|
19781
|
+
cacheRowVector(cache, memoryId, vector2, memories[i].updatedAt, content);
|
|
19735
19782
|
continue;
|
|
19736
19783
|
}
|
|
19737
19784
|
} catch {
|
|
@@ -19764,20 +19811,17 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
19764
19811
|
}
|
|
19765
19812
|
if (newEmbeddings) {
|
|
19766
19813
|
for (let j = 0; j < uncachedTexts.length; j++) {
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
memories[uncachedIndices[j]].updatedAt,
|
|
19772
|
-
memories[uncachedIndices[j]].content
|
|
19773
|
-
);
|
|
19814
|
+
const memory = memories[uncachedIndices[j]];
|
|
19815
|
+
const vector2 = Float32Array.from(newEmbeddings[j]);
|
|
19816
|
+
resolvedVectors.set(memory.uniqueId, vector2);
|
|
19817
|
+
cacheRowVector(cache, memory.uniqueId, vector2, memory.updatedAt, memory.content);
|
|
19774
19818
|
}
|
|
19775
19819
|
}
|
|
19776
19820
|
}
|
|
19777
19821
|
embeddedItems = memories.map((m) => ({
|
|
19778
19822
|
id: m.uniqueId,
|
|
19779
19823
|
content: m.content,
|
|
19780
|
-
embedding:
|
|
19824
|
+
embedding: resolvedVectors.get(m.uniqueId) ?? [],
|
|
19781
19825
|
createdAt: m.createdAt,
|
|
19782
19826
|
updatedAt: m.updatedAt,
|
|
19783
19827
|
proofCount: m.proofCount,
|
|
@@ -28181,6 +28225,9 @@ var WatermelonChatStorageAdapter = class {
|
|
|
28181
28225
|
searchChunks(queryVector, options) {
|
|
28182
28226
|
return searchChunksOp(this.ctx, queryVector, options);
|
|
28183
28227
|
}
|
|
28228
|
+
warmChunkCache(options) {
|
|
28229
|
+
return warmChunkVectorCacheOp(this.ctx, options);
|
|
28230
|
+
}
|
|
28184
28231
|
getSummary(conversationId) {
|
|
28185
28232
|
return getConversationSummaryOp(
|
|
28186
28233
|
createSummaryContext(this.ctx.database, this.ctx),
|