@anuma/sdk 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/{chunk-3RXNQBS3.mjs → chunk-IKPPX3GY.mjs} +60 -18
- package/dist/expo/index.cjs +60 -18
- package/dist/expo/index.d.mts +3 -0
- package/dist/expo/index.d.ts +3 -0
- package/dist/expo/index.mjs +1 -1
- package/dist/expo/{recall-GJ6RNZMF.mjs → recall-4JTNZBAW.mjs} +1 -1
- package/dist/index.cjs +13 -6
- package/dist/index.mjs +13 -6
- package/dist/react/{chunk-IMUF4U55.mjs → chunk-KQZ4KVYY.mjs} +60 -18
- package/dist/react/index.cjs +60 -18
- package/dist/react/index.d.mts +3 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.mjs +1 -1
- package/dist/react/{recall-NQ6ANFYN.mjs → recall-Z2HUBS2Y.mjs} +1 -1
- package/dist/server/{chunk-G3DC7QBH.mjs → chunk-KLJBJWWI.mjs} +60 -18
- package/dist/server/index.cjs +60 -18
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.mjs +1 -1
- package/dist/server/{recall-LFYTTIIY.mjs → recall-IF2HX7ZA.mjs} +1 -1
- package/package.json +1 -1
|
@@ -3501,6 +3501,20 @@ async function withEmbeddingRetry(call) {
|
|
|
3501
3501
|
if (threw) throw lastThrown;
|
|
3502
3502
|
return last;
|
|
3503
3503
|
}
|
|
3504
|
+
var EmbeddingHttpError = class extends Error {
|
|
3505
|
+
constructor(message, status) {
|
|
3506
|
+
super(message);
|
|
3507
|
+
this.name = "EmbeddingHttpError";
|
|
3508
|
+
this.status = status;
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
function isFatalEmbeddingError(err) {
|
|
3512
|
+
return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
|
|
3513
|
+
}
|
|
3514
|
+
function embeddingErrorFrom(response) {
|
|
3515
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
3516
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
3517
|
+
}
|
|
3504
3518
|
async function generateEmbedding(text, options) {
|
|
3505
3519
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
3506
3520
|
if (cache) {
|
|
@@ -3532,9 +3546,7 @@ async function generateEmbedding(text, options) {
|
|
|
3532
3546
|
})
|
|
3533
3547
|
);
|
|
3534
3548
|
if (response.error) {
|
|
3535
|
-
throw
|
|
3536
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3537
|
-
);
|
|
3549
|
+
throw embeddingErrorFrom(response);
|
|
3538
3550
|
}
|
|
3539
3551
|
if (!response.data?.data?.[0]?.embedding) {
|
|
3540
3552
|
throw new Error("No embedding returned from API");
|
|
@@ -3563,9 +3575,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
3563
3575
|
})
|
|
3564
3576
|
);
|
|
3565
3577
|
if (response.error) {
|
|
3566
|
-
throw
|
|
3567
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3568
|
-
);
|
|
3578
|
+
throw embeddingErrorFrom(response);
|
|
3569
3579
|
}
|
|
3570
3580
|
if (!response.data?.data) {
|
|
3571
3581
|
throw new Error("No embeddings returned from API");
|
|
@@ -3701,6 +3711,7 @@ async function embedAllMessages(ctx, options, filter) {
|
|
|
3701
3711
|
await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
|
|
3702
3712
|
embeddedCount++;
|
|
3703
3713
|
} catch (error) {
|
|
3714
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3704
3715
|
getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
|
|
3705
3716
|
}
|
|
3706
3717
|
}
|
|
@@ -3788,6 +3799,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3788
3799
|
}
|
|
3789
3800
|
}
|
|
3790
3801
|
} catch (error) {
|
|
3802
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3791
3803
|
getLogger().error("Failed to batch-embed short messages:", error);
|
|
3792
3804
|
}
|
|
3793
3805
|
}
|
|
@@ -3804,6 +3816,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3804
3816
|
await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
|
|
3805
3817
|
embeddedCount++;
|
|
3806
3818
|
} catch (error) {
|
|
3819
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3807
3820
|
getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
|
|
3808
3821
|
}
|
|
3809
3822
|
}
|
|
@@ -4300,6 +4313,7 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
4300
4313
|
updatedAt: item.updatedAt,
|
|
4301
4314
|
createdAt: item.createdAt,
|
|
4302
4315
|
eventTimeStart: item.eventTimeStart,
|
|
4316
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
4303
4317
|
eventTimeEnd: item.eventTimeEnd,
|
|
4304
4318
|
eventTimeKind: item.eventTimeKind,
|
|
4305
4319
|
similarity: cosineSimilarity(queryEmbedding, item.embedding)
|
|
@@ -4341,7 +4355,8 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
4341
4355
|
content: r.content,
|
|
4342
4356
|
similarity: r.similarity,
|
|
4343
4357
|
createdAt: item?.createdAt ?? item?.updatedAt,
|
|
4344
|
-
updatedAt: item?.updatedAt
|
|
4358
|
+
updatedAt: item?.updatedAt,
|
|
4359
|
+
sourceChunkIds: item?.sourceChunkIds
|
|
4345
4360
|
};
|
|
4346
4361
|
});
|
|
4347
4362
|
}
|
|
@@ -4380,6 +4395,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
4380
4395
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
4381
4396
|
updatedAt: item.updatedAt,
|
|
4382
4397
|
eventTimeStart: item.eventTimeStart,
|
|
4398
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
4383
4399
|
eventTimeEnd: item.eventTimeEnd,
|
|
4384
4400
|
eventTimeKind: item.eventTimeKind
|
|
4385
4401
|
});
|
|
@@ -4422,7 +4438,8 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
4422
4438
|
content: it.content,
|
|
4423
4439
|
similarity: (fused.get(id) ?? 0) * boostFor(id),
|
|
4424
4440
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
4425
|
-
updatedAt: it.updatedAt
|
|
4441
|
+
updatedAt: it.updatedAt,
|
|
4442
|
+
sourceChunkIds: it.sourceChunkIds
|
|
4426
4443
|
});
|
|
4427
4444
|
seen.add(id);
|
|
4428
4445
|
}
|
|
@@ -4460,13 +4477,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
4460
4477
|
combined = headSlice.map((r) => {
|
|
4461
4478
|
const v2 = v2ScoreById.get(r.uniqueId) ?? 0;
|
|
4462
4479
|
const ce = ceScoreById.get(r.uniqueId) ?? 0;
|
|
4463
|
-
return {
|
|
4464
|
-
uniqueId: r.uniqueId,
|
|
4465
|
-
content: r.content,
|
|
4466
|
-
similarity: v2 * (1 + ceWeight * ce),
|
|
4467
|
-
createdAt: r.createdAt,
|
|
4468
|
-
updatedAt: r.updatedAt
|
|
4469
|
-
};
|
|
4480
|
+
return { ...r, similarity: v2 * (1 + ceWeight * ce) };
|
|
4470
4481
|
});
|
|
4471
4482
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
4472
4483
|
} catch (err) {
|
|
@@ -4499,7 +4510,8 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
4499
4510
|
content: it.content,
|
|
4500
4511
|
similarity: fused.get(id) ?? 0,
|
|
4501
4512
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
4502
|
-
updatedAt: it.updatedAt
|
|
4513
|
+
updatedAt: it.updatedAt,
|
|
4514
|
+
sourceChunkIds: it.sourceChunkIds
|
|
4503
4515
|
});
|
|
4504
4516
|
seen.add(id);
|
|
4505
4517
|
}
|
|
@@ -4529,6 +4541,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
4529
4541
|
createdAt: orig?.createdAt,
|
|
4530
4542
|
updatedAt: orig?.updatedAt,
|
|
4531
4543
|
eventTimeStart: orig?.eventTimeStart,
|
|
4544
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
4532
4545
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
4533
4546
|
eventTimeKind: orig?.eventTimeKind
|
|
4534
4547
|
};
|
|
@@ -4592,6 +4605,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
4592
4605
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
4593
4606
|
updatedAt: item.updatedAt,
|
|
4594
4607
|
eventTimeStart: item.eventTimeStart,
|
|
4608
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
4595
4609
|
eventTimeEnd: item.eventTimeEnd,
|
|
4596
4610
|
eventTimeKind: item.eventTimeKind
|
|
4597
4611
|
};
|
|
@@ -4612,6 +4626,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
4612
4626
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
4613
4627
|
updatedAt: item.updatedAt,
|
|
4614
4628
|
eventTimeStart: item.eventTimeStart,
|
|
4629
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
4615
4630
|
eventTimeEnd: item.eventTimeEnd,
|
|
4616
4631
|
eventTimeKind: item.eventTimeKind
|
|
4617
4632
|
});
|
|
@@ -4663,6 +4678,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
4663
4678
|
createdAt: orig?.createdAt,
|
|
4664
4679
|
updatedAt: orig?.updatedAt,
|
|
4665
4680
|
eventTimeStart: orig?.eventTimeStart,
|
|
4681
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
4666
4682
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
4667
4683
|
eventTimeKind: orig?.eventTimeKind
|
|
4668
4684
|
};
|
|
@@ -4804,6 +4820,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
4804
4820
|
updatedAt: m.updatedAt,
|
|
4805
4821
|
proofCount: m.proofCount,
|
|
4806
4822
|
eventTimeStart: m.eventTimeStart,
|
|
4823
|
+
sourceChunkIds: m.sourceChunkIds,
|
|
4807
4824
|
eventTimeEnd: m.eventTimeEnd,
|
|
4808
4825
|
eventTimeKind: normalizeEventTimeKind(m.eventTimeKind)
|
|
4809
4826
|
}));
|
|
@@ -4994,7 +5011,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
4994
5011
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
4995
5012
|
);
|
|
4996
5013
|
}
|
|
4997
|
-
const { recall: recall2 } = await import("./recall-
|
|
5014
|
+
const { recall: recall2 } = await import("./recall-Z2HUBS2Y.mjs");
|
|
4998
5015
|
const result = await recall2(
|
|
4999
5016
|
query,
|
|
5000
5017
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
|
@@ -5462,7 +5479,31 @@ async function recall(query, ctx, options = {}) {
|
|
|
5462
5479
|
m.scoreBreakdown.fused = r.similarity;
|
|
5463
5480
|
byId.set(key, m);
|
|
5464
5481
|
}
|
|
5465
|
-
const
|
|
5482
|
+
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
5483
|
+
const selectWith = (suppressed2) => {
|
|
5484
|
+
const out = [];
|
|
5485
|
+
for (const m of ordered) {
|
|
5486
|
+
if (out.length >= limit) break;
|
|
5487
|
+
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
5488
|
+
out.push(m);
|
|
5489
|
+
}
|
|
5490
|
+
return out;
|
|
5491
|
+
};
|
|
5492
|
+
const provenanceOf = (selected) => {
|
|
5493
|
+
const s = /* @__PURE__ */ new Set();
|
|
5494
|
+
for (const m of selected) {
|
|
5495
|
+
if (m.kind === "fact" && m.sourceChunkIds) for (const id of m.sourceChunkIds) s.add(id);
|
|
5496
|
+
}
|
|
5497
|
+
return s;
|
|
5498
|
+
};
|
|
5499
|
+
let suppressed = /* @__PURE__ */ new Set();
|
|
5500
|
+
let memories = selectWith(suppressed);
|
|
5501
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
5502
|
+
const next = provenanceOf(memories);
|
|
5503
|
+
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
5504
|
+
suppressed = next;
|
|
5505
|
+
memories = selectWith(suppressed);
|
|
5506
|
+
}
|
|
5466
5507
|
return {
|
|
5467
5508
|
memories,
|
|
5468
5509
|
usedBudget,
|
|
@@ -5483,6 +5524,7 @@ function toFactMemory(r) {
|
|
|
5483
5524
|
...r.eventTimeStart !== void 0 && { eventTimeStart: r.eventTimeStart },
|
|
5484
5525
|
...r.eventTimeEnd !== void 0 && { eventTimeEnd: r.eventTimeEnd },
|
|
5485
5526
|
...r.eventTimeKind !== void 0 && { eventTimeKind: r.eventTimeKind },
|
|
5527
|
+
...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
|
|
5486
5528
|
// r.similarity from searchVaultMemoriesWithSize is the fused score
|
|
5487
5529
|
// (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
|
|
5488
5530
|
// default) and pure cosine when useFusion=false. The breakdown
|
package/dist/react/index.cjs
CHANGED
|
@@ -3093,6 +3093,13 @@ async function withEmbeddingRetry(call) {
|
|
|
3093
3093
|
if (threw) throw lastThrown;
|
|
3094
3094
|
return last;
|
|
3095
3095
|
}
|
|
3096
|
+
function isFatalEmbeddingError(err) {
|
|
3097
|
+
return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
|
|
3098
|
+
}
|
|
3099
|
+
function embeddingErrorFrom(response) {
|
|
3100
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
3101
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
3102
|
+
}
|
|
3096
3103
|
async function generateEmbedding(text11, options) {
|
|
3097
3104
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
3098
3105
|
if (cache) {
|
|
@@ -3124,9 +3131,7 @@ async function generateEmbedding(text11, options) {
|
|
|
3124
3131
|
})
|
|
3125
3132
|
);
|
|
3126
3133
|
if (response.error) {
|
|
3127
|
-
throw
|
|
3128
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3129
|
-
);
|
|
3134
|
+
throw embeddingErrorFrom(response);
|
|
3130
3135
|
}
|
|
3131
3136
|
if (!response.data?.data?.[0]?.embedding) {
|
|
3132
3137
|
throw new Error("No embedding returned from API");
|
|
@@ -3153,9 +3158,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
3153
3158
|
})
|
|
3154
3159
|
);
|
|
3155
3160
|
if (response.error) {
|
|
3156
|
-
throw
|
|
3157
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
3158
|
-
);
|
|
3161
|
+
throw embeddingErrorFrom(response);
|
|
3159
3162
|
}
|
|
3160
3163
|
if (!response.data?.data) {
|
|
3161
3164
|
throw new Error("No embeddings returned from API");
|
|
@@ -3291,6 +3294,7 @@ async function embedAllMessages(ctx, options, filter) {
|
|
|
3291
3294
|
await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
|
|
3292
3295
|
embeddedCount++;
|
|
3293
3296
|
} catch (error) {
|
|
3297
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3294
3298
|
getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
|
|
3295
3299
|
}
|
|
3296
3300
|
}
|
|
@@ -3378,6 +3382,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3378
3382
|
}
|
|
3379
3383
|
}
|
|
3380
3384
|
} catch (error) {
|
|
3385
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3381
3386
|
getLogger().error("Failed to batch-embed short messages:", error);
|
|
3382
3387
|
}
|
|
3383
3388
|
}
|
|
@@ -3394,12 +3399,13 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3394
3399
|
await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
|
|
3395
3400
|
embeddedCount++;
|
|
3396
3401
|
} catch (error) {
|
|
3402
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
3397
3403
|
getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
|
|
3398
3404
|
}
|
|
3399
3405
|
}
|
|
3400
3406
|
return embeddedCount;
|
|
3401
3407
|
}
|
|
3402
|
-
var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
|
|
3408
|
+
var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
|
|
3403
3409
|
var init_embeddings = __esm({
|
|
3404
3410
|
"src/lib/memoryEngine/embeddings.ts"() {
|
|
3405
3411
|
"use strict";
|
|
@@ -3411,6 +3417,13 @@ var init_embeddings = __esm({
|
|
|
3411
3417
|
init_constants();
|
|
3412
3418
|
DEFAULT_MIN_CONTENT_LENGTH = 10;
|
|
3413
3419
|
EMBED_MAX_ATTEMPTS = 4;
|
|
3420
|
+
EmbeddingHttpError = class extends Error {
|
|
3421
|
+
constructor(message, status) {
|
|
3422
|
+
super(message);
|
|
3423
|
+
this.name = "EmbeddingHttpError";
|
|
3424
|
+
this.status = status;
|
|
3425
|
+
}
|
|
3426
|
+
};
|
|
3414
3427
|
DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
3415
3428
|
DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
3416
3429
|
}
|
|
@@ -5877,7 +5890,31 @@ async function recall(query, ctx, options = {}) {
|
|
|
5877
5890
|
m.scoreBreakdown.fused = r.similarity;
|
|
5878
5891
|
byId.set(key, m);
|
|
5879
5892
|
}
|
|
5880
|
-
const
|
|
5893
|
+
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
5894
|
+
const selectWith = (suppressed2) => {
|
|
5895
|
+
const out = [];
|
|
5896
|
+
for (const m of ordered) {
|
|
5897
|
+
if (out.length >= limit) break;
|
|
5898
|
+
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
5899
|
+
out.push(m);
|
|
5900
|
+
}
|
|
5901
|
+
return out;
|
|
5902
|
+
};
|
|
5903
|
+
const provenanceOf = (selected) => {
|
|
5904
|
+
const s = /* @__PURE__ */ new Set();
|
|
5905
|
+
for (const m of selected) {
|
|
5906
|
+
if (m.kind === "fact" && m.sourceChunkIds) for (const id of m.sourceChunkIds) s.add(id);
|
|
5907
|
+
}
|
|
5908
|
+
return s;
|
|
5909
|
+
};
|
|
5910
|
+
let suppressed = /* @__PURE__ */ new Set();
|
|
5911
|
+
let memories = selectWith(suppressed);
|
|
5912
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
5913
|
+
const next = provenanceOf(memories);
|
|
5914
|
+
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
5915
|
+
suppressed = next;
|
|
5916
|
+
memories = selectWith(suppressed);
|
|
5917
|
+
}
|
|
5881
5918
|
return {
|
|
5882
5919
|
memories,
|
|
5883
5920
|
usedBudget,
|
|
@@ -5898,6 +5935,7 @@ function toFactMemory(r) {
|
|
|
5898
5935
|
...r.eventTimeStart !== void 0 && { eventTimeStart: r.eventTimeStart },
|
|
5899
5936
|
...r.eventTimeEnd !== void 0 && { eventTimeEnd: r.eventTimeEnd },
|
|
5900
5937
|
...r.eventTimeKind !== void 0 && { eventTimeKind: r.eventTimeKind },
|
|
5938
|
+
...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
|
|
5901
5939
|
// r.similarity from searchVaultMemoriesWithSize is the fused score
|
|
5902
5940
|
// (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
|
|
5903
5941
|
// default) and pure cosine when useFusion=false. The breakdown
|
|
@@ -6012,6 +6050,7 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
6012
6050
|
updatedAt: item.updatedAt,
|
|
6013
6051
|
createdAt: item.createdAt,
|
|
6014
6052
|
eventTimeStart: item.eventTimeStart,
|
|
6053
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
6015
6054
|
eventTimeEnd: item.eventTimeEnd,
|
|
6016
6055
|
eventTimeKind: item.eventTimeKind,
|
|
6017
6056
|
similarity: cosineSimilarity(queryEmbedding, item.embedding)
|
|
@@ -6053,7 +6092,8 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
6053
6092
|
content: r.content,
|
|
6054
6093
|
similarity: r.similarity,
|
|
6055
6094
|
createdAt: item?.createdAt ?? item?.updatedAt,
|
|
6056
|
-
updatedAt: item?.updatedAt
|
|
6095
|
+
updatedAt: item?.updatedAt,
|
|
6096
|
+
sourceChunkIds: item?.sourceChunkIds
|
|
6057
6097
|
};
|
|
6058
6098
|
});
|
|
6059
6099
|
}
|
|
@@ -6092,6 +6132,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
6092
6132
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
6093
6133
|
updatedAt: item.updatedAt,
|
|
6094
6134
|
eventTimeStart: item.eventTimeStart,
|
|
6135
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
6095
6136
|
eventTimeEnd: item.eventTimeEnd,
|
|
6096
6137
|
eventTimeKind: item.eventTimeKind
|
|
6097
6138
|
});
|
|
@@ -6134,7 +6175,8 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
6134
6175
|
content: it.content,
|
|
6135
6176
|
similarity: (fused.get(id) ?? 0) * boostFor(id),
|
|
6136
6177
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
6137
|
-
updatedAt: it.updatedAt
|
|
6178
|
+
updatedAt: it.updatedAt,
|
|
6179
|
+
sourceChunkIds: it.sourceChunkIds
|
|
6138
6180
|
});
|
|
6139
6181
|
seen.add(id);
|
|
6140
6182
|
}
|
|
@@ -6172,13 +6214,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6172
6214
|
combined = headSlice.map((r) => {
|
|
6173
6215
|
const v2 = v2ScoreById.get(r.uniqueId) ?? 0;
|
|
6174
6216
|
const ce = ceScoreById.get(r.uniqueId) ?? 0;
|
|
6175
|
-
return {
|
|
6176
|
-
uniqueId: r.uniqueId,
|
|
6177
|
-
content: r.content,
|
|
6178
|
-
similarity: v2 * (1 + ceWeight * ce),
|
|
6179
|
-
createdAt: r.createdAt,
|
|
6180
|
-
updatedAt: r.updatedAt
|
|
6181
|
-
};
|
|
6217
|
+
return { ...r, similarity: v2 * (1 + ceWeight * ce) };
|
|
6182
6218
|
});
|
|
6183
6219
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
6184
6220
|
} catch (err) {
|
|
@@ -6211,7 +6247,8 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6211
6247
|
content: it.content,
|
|
6212
6248
|
similarity: fused.get(id) ?? 0,
|
|
6213
6249
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
6214
|
-
updatedAt: it.updatedAt
|
|
6250
|
+
updatedAt: it.updatedAt,
|
|
6251
|
+
sourceChunkIds: it.sourceChunkIds
|
|
6215
6252
|
});
|
|
6216
6253
|
seen.add(id);
|
|
6217
6254
|
}
|
|
@@ -6241,6 +6278,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
6241
6278
|
createdAt: orig?.createdAt,
|
|
6242
6279
|
updatedAt: orig?.updatedAt,
|
|
6243
6280
|
eventTimeStart: orig?.eventTimeStart,
|
|
6281
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
6244
6282
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
6245
6283
|
eventTimeKind: orig?.eventTimeKind
|
|
6246
6284
|
};
|
|
@@ -6304,6 +6342,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6304
6342
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
6305
6343
|
updatedAt: item.updatedAt,
|
|
6306
6344
|
eventTimeStart: item.eventTimeStart,
|
|
6345
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
6307
6346
|
eventTimeEnd: item.eventTimeEnd,
|
|
6308
6347
|
eventTimeKind: item.eventTimeKind
|
|
6309
6348
|
};
|
|
@@ -6324,6 +6363,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6324
6363
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
6325
6364
|
updatedAt: item.updatedAt,
|
|
6326
6365
|
eventTimeStart: item.eventTimeStart,
|
|
6366
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
6327
6367
|
eventTimeEnd: item.eventTimeEnd,
|
|
6328
6368
|
eventTimeKind: item.eventTimeKind
|
|
6329
6369
|
});
|
|
@@ -6375,6 +6415,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
6375
6415
|
createdAt: orig?.createdAt,
|
|
6376
6416
|
updatedAt: orig?.updatedAt,
|
|
6377
6417
|
eventTimeStart: orig?.eventTimeStart,
|
|
6418
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
6378
6419
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
6379
6420
|
eventTimeKind: orig?.eventTimeKind
|
|
6380
6421
|
};
|
|
@@ -6516,6 +6557,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
6516
6557
|
updatedAt: m.updatedAt,
|
|
6517
6558
|
proofCount: m.proofCount,
|
|
6518
6559
|
eventTimeStart: m.eventTimeStart,
|
|
6560
|
+
sourceChunkIds: m.sourceChunkIds,
|
|
6519
6561
|
eventTimeEnd: m.eventTimeEnd,
|
|
6520
6562
|
eventTimeKind: normalizeEventTimeKind(m.eventTimeKind)
|
|
6521
6563
|
}));
|
package/dist/react/index.d.mts
CHANGED
|
@@ -5979,6 +5979,9 @@ interface VaultSearchResult {
|
|
|
5979
5979
|
eventTimeStart?: number | null;
|
|
5980
5980
|
eventTimeEnd?: number | null;
|
|
5981
5981
|
eventTimeKind?: "point" | "range" | "ongoing" | null;
|
|
5982
|
+
/** Message ids this fact was extracted from (provenance). recall() uses
|
|
5983
|
+
* these to suppress the originating chunk in the chunk lane. */
|
|
5984
|
+
sourceChunkIds?: string[] | null;
|
|
5982
5985
|
}
|
|
5983
5986
|
/**
|
|
5984
5987
|
* Search vault memories by semantic similarity. Returns structured results
|
package/dist/react/index.d.ts
CHANGED
|
@@ -5979,6 +5979,9 @@ interface VaultSearchResult {
|
|
|
5979
5979
|
eventTimeStart?: number | null;
|
|
5980
5980
|
eventTimeEnd?: number | null;
|
|
5981
5981
|
eventTimeKind?: "point" | "range" | "ongoing" | null;
|
|
5982
|
+
/** Message ids this fact was extracted from (provenance). recall() uses
|
|
5983
|
+
* these to suppress the originating chunk in the chunk lane. */
|
|
5984
|
+
sourceChunkIds?: string[] | null;
|
|
5982
5985
|
}
|
|
5983
5986
|
/**
|
|
5984
5987
|
* Search vault memories by semantic similarity. Returns structured results
|
package/dist/react/index.mjs
CHANGED
|
@@ -17328,6 +17328,20 @@ async function withEmbeddingRetry(call) {
|
|
|
17328
17328
|
if (threw) throw lastThrown;
|
|
17329
17329
|
return last;
|
|
17330
17330
|
}
|
|
17331
|
+
var EmbeddingHttpError = class extends Error {
|
|
17332
|
+
constructor(message, status) {
|
|
17333
|
+
super(message);
|
|
17334
|
+
this.name = "EmbeddingHttpError";
|
|
17335
|
+
this.status = status;
|
|
17336
|
+
}
|
|
17337
|
+
};
|
|
17338
|
+
function isFatalEmbeddingError(err) {
|
|
17339
|
+
return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
|
|
17340
|
+
}
|
|
17341
|
+
function embeddingErrorFrom(response) {
|
|
17342
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
17343
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
17344
|
+
}
|
|
17331
17345
|
async function generateEmbedding(text, options) {
|
|
17332
17346
|
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
17333
17347
|
if (cache) {
|
|
@@ -17359,9 +17373,7 @@ async function generateEmbedding(text, options) {
|
|
|
17359
17373
|
})
|
|
17360
17374
|
);
|
|
17361
17375
|
if (response.error) {
|
|
17362
|
-
throw
|
|
17363
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
17364
|
-
);
|
|
17376
|
+
throw embeddingErrorFrom(response);
|
|
17365
17377
|
}
|
|
17366
17378
|
if (!response.data?.data?.[0]?.embedding) {
|
|
17367
17379
|
throw new Error("No embedding returned from API");
|
|
@@ -17390,9 +17402,7 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
|
|
|
17390
17402
|
})
|
|
17391
17403
|
);
|
|
17392
17404
|
if (response.error) {
|
|
17393
|
-
throw
|
|
17394
|
-
typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
|
|
17395
|
-
);
|
|
17405
|
+
throw embeddingErrorFrom(response);
|
|
17396
17406
|
}
|
|
17397
17407
|
if (!response.data?.data) {
|
|
17398
17408
|
throw new Error("No embeddings returned from API");
|
|
@@ -17528,6 +17538,7 @@ async function embedAllMessages(ctx, options, filter) {
|
|
|
17528
17538
|
await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
|
|
17529
17539
|
embeddedCount++;
|
|
17530
17540
|
} catch (error) {
|
|
17541
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
17531
17542
|
getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
|
|
17532
17543
|
}
|
|
17533
17544
|
}
|
|
@@ -17615,6 +17626,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
17615
17626
|
}
|
|
17616
17627
|
}
|
|
17617
17628
|
} catch (error) {
|
|
17629
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
17618
17630
|
getLogger().error("Failed to batch-embed short messages:", error);
|
|
17619
17631
|
}
|
|
17620
17632
|
}
|
|
@@ -17631,6 +17643,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
17631
17643
|
await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
|
|
17632
17644
|
embeddedCount++;
|
|
17633
17645
|
} catch (error) {
|
|
17646
|
+
if (isFatalEmbeddingError(error)) throw error;
|
|
17634
17647
|
getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
|
|
17635
17648
|
}
|
|
17636
17649
|
}
|
|
@@ -18127,6 +18140,7 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
18127
18140
|
updatedAt: item.updatedAt,
|
|
18128
18141
|
createdAt: item.createdAt,
|
|
18129
18142
|
eventTimeStart: item.eventTimeStart,
|
|
18143
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
18130
18144
|
eventTimeEnd: item.eventTimeEnd,
|
|
18131
18145
|
eventTimeKind: item.eventTimeKind,
|
|
18132
18146
|
similarity: cosineSimilarity(queryEmbedding, item.embedding)
|
|
@@ -18168,7 +18182,8 @@ function rankVaultMemories(_query, queryEmbedding, items, options) {
|
|
|
18168
18182
|
content: r.content,
|
|
18169
18183
|
similarity: r.similarity,
|
|
18170
18184
|
createdAt: item?.createdAt ?? item?.updatedAt,
|
|
18171
|
-
updatedAt: item?.updatedAt
|
|
18185
|
+
updatedAt: item?.updatedAt,
|
|
18186
|
+
sourceChunkIds: item?.sourceChunkIds
|
|
18172
18187
|
};
|
|
18173
18188
|
});
|
|
18174
18189
|
}
|
|
@@ -18207,6 +18222,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
18207
18222
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
18208
18223
|
updatedAt: item.updatedAt,
|
|
18209
18224
|
eventTimeStart: item.eventTimeStart,
|
|
18225
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
18210
18226
|
eventTimeEnd: item.eventTimeEnd,
|
|
18211
18227
|
eventTimeKind: item.eventTimeKind
|
|
18212
18228
|
});
|
|
@@ -18249,7 +18265,8 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
|
|
|
18249
18265
|
content: it.content,
|
|
18250
18266
|
similarity: (fused.get(id) ?? 0) * boostFor(id),
|
|
18251
18267
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
18252
|
-
updatedAt: it.updatedAt
|
|
18268
|
+
updatedAt: it.updatedAt,
|
|
18269
|
+
sourceChunkIds: it.sourceChunkIds
|
|
18253
18270
|
});
|
|
18254
18271
|
seen.add(id);
|
|
18255
18272
|
}
|
|
@@ -18287,13 +18304,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
18287
18304
|
combined = headSlice.map((r) => {
|
|
18288
18305
|
const v2 = v2ScoreById.get(r.uniqueId) ?? 0;
|
|
18289
18306
|
const ce = ceScoreById.get(r.uniqueId) ?? 0;
|
|
18290
|
-
return {
|
|
18291
|
-
uniqueId: r.uniqueId,
|
|
18292
|
-
content: r.content,
|
|
18293
|
-
similarity: v2 * (1 + ceWeight * ce),
|
|
18294
|
-
createdAt: r.createdAt,
|
|
18295
|
-
updatedAt: r.updatedAt
|
|
18296
|
-
};
|
|
18307
|
+
return { ...r, similarity: v2 * (1 + ceWeight * ce) };
|
|
18297
18308
|
});
|
|
18298
18309
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
18299
18310
|
} catch (err) {
|
|
@@ -18326,7 +18337,8 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
18326
18337
|
content: it.content,
|
|
18327
18338
|
similarity: fused.get(id) ?? 0,
|
|
18328
18339
|
createdAt: it.createdAt ?? it.updatedAt,
|
|
18329
|
-
updatedAt: it.updatedAt
|
|
18340
|
+
updatedAt: it.updatedAt,
|
|
18341
|
+
sourceChunkIds: it.sourceChunkIds
|
|
18330
18342
|
});
|
|
18331
18343
|
seen.add(id);
|
|
18332
18344
|
}
|
|
@@ -18356,6 +18368,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
|
|
|
18356
18368
|
createdAt: orig?.createdAt,
|
|
18357
18369
|
updatedAt: orig?.updatedAt,
|
|
18358
18370
|
eventTimeStart: orig?.eventTimeStart,
|
|
18371
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
18359
18372
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
18360
18373
|
eventTimeKind: orig?.eventTimeKind
|
|
18361
18374
|
};
|
|
@@ -18419,6 +18432,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
18419
18432
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
18420
18433
|
updatedAt: item.updatedAt,
|
|
18421
18434
|
eventTimeStart: item.eventTimeStart,
|
|
18435
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
18422
18436
|
eventTimeEnd: item.eventTimeEnd,
|
|
18423
18437
|
eventTimeKind: item.eventTimeKind
|
|
18424
18438
|
};
|
|
@@ -18439,6 +18453,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
18439
18453
|
createdAt: item.createdAt ?? item.updatedAt,
|
|
18440
18454
|
updatedAt: item.updatedAt,
|
|
18441
18455
|
eventTimeStart: item.eventTimeStart,
|
|
18456
|
+
sourceChunkIds: item.sourceChunkIds,
|
|
18442
18457
|
eventTimeEnd: item.eventTimeEnd,
|
|
18443
18458
|
eventTimeKind: item.eventTimeKind
|
|
18444
18459
|
});
|
|
@@ -18490,6 +18505,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
18490
18505
|
createdAt: orig?.createdAt,
|
|
18491
18506
|
updatedAt: orig?.updatedAt,
|
|
18492
18507
|
eventTimeStart: orig?.eventTimeStart,
|
|
18508
|
+
sourceChunkIds: orig?.sourceChunkIds,
|
|
18493
18509
|
eventTimeEnd: orig?.eventTimeEnd,
|
|
18494
18510
|
eventTimeKind: orig?.eventTimeKind
|
|
18495
18511
|
};
|
|
@@ -18631,6 +18647,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
|
|
|
18631
18647
|
updatedAt: m.updatedAt,
|
|
18632
18648
|
proofCount: m.proofCount,
|
|
18633
18649
|
eventTimeStart: m.eventTimeStart,
|
|
18650
|
+
sourceChunkIds: m.sourceChunkIds,
|
|
18634
18651
|
eventTimeEnd: m.eventTimeEnd,
|
|
18635
18652
|
eventTimeKind: normalizeEventTimeKind(m.eventTimeKind)
|
|
18636
18653
|
}));
|
|
@@ -18821,7 +18838,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
18821
18838
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
18822
18839
|
);
|
|
18823
18840
|
}
|
|
18824
|
-
const { recall: recall2 } = await import("./recall-
|
|
18841
|
+
const { recall: recall2 } = await import("./recall-IF2HX7ZA.mjs");
|
|
18825
18842
|
const result = await recall2(
|
|
18826
18843
|
query,
|
|
18827
18844
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
|
@@ -19289,7 +19306,31 @@ async function recall(query, ctx, options = {}) {
|
|
|
19289
19306
|
m.scoreBreakdown.fused = r.similarity;
|
|
19290
19307
|
byId.set(key, m);
|
|
19291
19308
|
}
|
|
19292
|
-
const
|
|
19309
|
+
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
19310
|
+
const selectWith = (suppressed2) => {
|
|
19311
|
+
const out = [];
|
|
19312
|
+
for (const m of ordered) {
|
|
19313
|
+
if (out.length >= limit) break;
|
|
19314
|
+
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
19315
|
+
out.push(m);
|
|
19316
|
+
}
|
|
19317
|
+
return out;
|
|
19318
|
+
};
|
|
19319
|
+
const provenanceOf = (selected) => {
|
|
19320
|
+
const s = /* @__PURE__ */ new Set();
|
|
19321
|
+
for (const m of selected) {
|
|
19322
|
+
if (m.kind === "fact" && m.sourceChunkIds) for (const id of m.sourceChunkIds) s.add(id);
|
|
19323
|
+
}
|
|
19324
|
+
return s;
|
|
19325
|
+
};
|
|
19326
|
+
let suppressed = /* @__PURE__ */ new Set();
|
|
19327
|
+
let memories = selectWith(suppressed);
|
|
19328
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
19329
|
+
const next = provenanceOf(memories);
|
|
19330
|
+
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
19331
|
+
suppressed = next;
|
|
19332
|
+
memories = selectWith(suppressed);
|
|
19333
|
+
}
|
|
19293
19334
|
return {
|
|
19294
19335
|
memories,
|
|
19295
19336
|
usedBudget,
|
|
@@ -19310,6 +19351,7 @@ function toFactMemory(r) {
|
|
|
19310
19351
|
...r.eventTimeStart !== void 0 && { eventTimeStart: r.eventTimeStart },
|
|
19311
19352
|
...r.eventTimeEnd !== void 0 && { eventTimeEnd: r.eventTimeEnd },
|
|
19312
19353
|
...r.eventTimeKind !== void 0 && { eventTimeKind: r.eventTimeKind },
|
|
19354
|
+
...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
|
|
19313
19355
|
// r.similarity from searchVaultMemoriesWithSize is the fused score
|
|
19314
19356
|
// (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
|
|
19315
19357
|
// default) and pure cosine when useFusion=false. The breakdown
|