@anuma/sdk 6.19.2 → 6.21.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-7HRJOHW4.mjs → chunk-CIMZZ7GQ.mjs} +59 -12
- package/dist/expo/index.cjs +142 -43
- package/dist/expo/index.d.mts +171 -2
- package/dist/expo/index.d.ts +171 -2
- package/dist/expo/index.mjs +85 -33
- package/dist/expo/{recall-SCMH2R24.mjs → recall-FQQGE6A2.mjs} +1 -1
- package/dist/react/{chunk-M53NXLZS.mjs → chunk-JRVAUZHM.mjs} +59 -12
- package/dist/react/index.cjs +142 -43
- package/dist/react/index.d.mts +171 -2
- package/dist/react/index.d.ts +171 -2
- package/dist/react/index.mjs +85 -33
- package/dist/react/{recall-B3M4BWQ2.mjs → recall-7Q3V337H.mjs} +1 -1
- package/dist/server/{chunk-X5EZQFGR.mjs → chunk-4DSDATYG.mjs} +59 -12
- package/dist/server/index.cjs +142 -43
- package/dist/server/index.d.mts +171 -2
- package/dist/server/index.d.ts +171 -2
- package/dist/server/index.mjs +85 -33
- package/dist/server/{recall-M3KBKU74.mjs → recall-HA4UX4BB.mjs} +1 -1
- package/dist/telemetry/index.cjs +20 -0
- package/dist/telemetry/index.d.mts +63 -1
- package/dist/telemetry/index.d.ts +63 -1
- package/dist/telemetry/index.mjs +20 -0
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -179,7 +179,7 @@ import {
|
|
|
179
179
|
updateVaultMemoryOp,
|
|
180
180
|
useEncryption,
|
|
181
181
|
vaultMemoryToStored
|
|
182
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-JRVAUZHM.mjs";
|
|
183
183
|
import {
|
|
184
184
|
PiiRedactor,
|
|
185
185
|
createStreamingDeAnonymizer,
|
|
@@ -7464,6 +7464,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
7464
7464
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
7465
7465
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
7466
7466
|
let supersedeTargetIds = [];
|
|
7467
|
+
let consolidationDecidedCreate = false;
|
|
7467
7468
|
let supersedeContent;
|
|
7468
7469
|
let prepared;
|
|
7469
7470
|
if (enableAutoMerge) {
|
|
@@ -7491,8 +7492,12 @@ async function retain(content, ctx, options = {}) {
|
|
|
7491
7492
|
const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
|
|
7492
7493
|
if (outcome) {
|
|
7493
7494
|
if ("done" in outcome) return outcome.done;
|
|
7494
|
-
|
|
7495
|
-
|
|
7495
|
+
if ("create" in outcome) {
|
|
7496
|
+
consolidationDecidedCreate = true;
|
|
7497
|
+
} else {
|
|
7498
|
+
supersedeTargetIds = outcome.supersede;
|
|
7499
|
+
supersedeContent = outcome.content;
|
|
7500
|
+
}
|
|
7496
7501
|
}
|
|
7497
7502
|
}
|
|
7498
7503
|
if (supersedeTargetIds.length === 0) {
|
|
@@ -7542,7 +7547,14 @@ async function retain(content, ctx, options = {}) {
|
|
|
7542
7547
|
action: "merge",
|
|
7543
7548
|
memoryId: targetId,
|
|
7544
7549
|
targetId,
|
|
7545
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
7550
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
7551
|
+
similarity: matches[0].similarity,
|
|
7552
|
+
// Stage 1 may have run and explicitly said `create`, and Stage 2
|
|
7553
|
+
// then found a strict-cosine match anyway. Reporting the decision
|
|
7554
|
+
// here is what makes that DISAGREEMENT visible — without it the
|
|
7555
|
+
// model's create silently vanished from the distribution whenever
|
|
7556
|
+
// the cosine stage won.
|
|
7557
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
7546
7558
|
};
|
|
7547
7559
|
}
|
|
7548
7560
|
await assertMergeTargetGoneOrThrow(ctx, targetId);
|
|
@@ -7555,12 +7567,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
7555
7567
|
const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
|
|
7556
7568
|
const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
7557
7569
|
if (options.respectTombstones) {
|
|
7558
|
-
const
|
|
7570
|
+
const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
|
|
7559
7571
|
threshold,
|
|
7560
7572
|
folderId: options.folderId
|
|
7561
7573
|
});
|
|
7562
|
-
if (
|
|
7563
|
-
return {
|
|
7574
|
+
if (tombstone) {
|
|
7575
|
+
return {
|
|
7576
|
+
action: "suppressed",
|
|
7577
|
+
memoryId: tombstone.id,
|
|
7578
|
+
tombstoneId: tombstone.id,
|
|
7579
|
+
proofCount: 0,
|
|
7580
|
+
similarity: tombstone.similarity
|
|
7581
|
+
};
|
|
7564
7582
|
}
|
|
7565
7583
|
}
|
|
7566
7584
|
const createOpts = {
|
|
@@ -7627,7 +7645,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
7627
7645
|
action: "supersede",
|
|
7628
7646
|
memoryId: created2.uniqueId,
|
|
7629
7647
|
targetId: primaryTargetId,
|
|
7630
|
-
proofCount: 1
|
|
7648
|
+
proofCount: 1,
|
|
7649
|
+
consolidation: "supersede"
|
|
7631
7650
|
};
|
|
7632
7651
|
}
|
|
7633
7652
|
notifyConsolidationFallback(
|
|
@@ -7641,7 +7660,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
7641
7660
|
return {
|
|
7642
7661
|
action: "create",
|
|
7643
7662
|
memoryId: created.uniqueId,
|
|
7644
|
-
proofCount: 1
|
|
7663
|
+
proofCount: 1,
|
|
7664
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
7645
7665
|
};
|
|
7646
7666
|
}
|
|
7647
7667
|
function unionStrings(a, b) {
|
|
@@ -7671,7 +7691,7 @@ async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
|
|
|
7671
7691
|
bestId = row.uniqueId;
|
|
7672
7692
|
}
|
|
7673
7693
|
}
|
|
7674
|
-
return bestId;
|
|
7694
|
+
return bestId === null ? null : { id: bestId, similarity: bestSim };
|
|
7675
7695
|
}
|
|
7676
7696
|
function pickEventTimeUpdate(existing, incoming) {
|
|
7677
7697
|
if (incoming === void 0 || incoming === null) return void 0;
|
|
@@ -7713,7 +7733,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
7713
7733
|
}));
|
|
7714
7734
|
const { consolidateMemory: doConsolidate } = await import("./consolidate-URHGJT7I.mjs");
|
|
7715
7735
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
7716
|
-
if (decision.action === "create") return null;
|
|
7736
|
+
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
7717
7737
|
if (decision.action === "supersede" && decision.content) {
|
|
7718
7738
|
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
7719
7739
|
if (requestedIds.length === 0) return null;
|
|
@@ -7772,7 +7792,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
7772
7792
|
action: "merge",
|
|
7773
7793
|
memoryId: decision.targetId,
|
|
7774
7794
|
targetId: decision.targetId,
|
|
7775
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
7795
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
7796
|
+
consolidation: "noop"
|
|
7776
7797
|
}
|
|
7777
7798
|
};
|
|
7778
7799
|
}
|
|
@@ -7825,7 +7846,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
7825
7846
|
action: "update",
|
|
7826
7847
|
memoryId: decision.targetId,
|
|
7827
7848
|
targetId: decision.targetId,
|
|
7828
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
7849
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
7850
|
+
consolidation: "update"
|
|
7829
7851
|
}
|
|
7830
7852
|
};
|
|
7831
7853
|
}
|
|
@@ -7967,6 +7989,11 @@ Extract durable user facts.`,
|
|
|
7967
7989
|
fallbackSourceId,
|
|
7968
7990
|
options.userIdentity ?? []
|
|
7969
7991
|
);
|
|
7992
|
+
const rawCandidates = parsed.candidates;
|
|
7993
|
+
options.onCandidatesParsed?.({
|
|
7994
|
+
rawCount: Array.isArray(rawCandidates) ? rawCandidates.length : 0,
|
|
7995
|
+
validCount: candidates.length
|
|
7996
|
+
});
|
|
7970
7997
|
if (!redactor) return candidates;
|
|
7971
7998
|
const restored = restoreCandidates(candidates, redactor, options.userIdentity ?? []);
|
|
7972
7999
|
if (candidates.length > 0 && restored.length === 0) {
|
|
@@ -8003,8 +8030,12 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
8003
8030
|
let exhaustedEmpty = false;
|
|
8004
8031
|
let exhaustedFailure;
|
|
8005
8032
|
let droppedAfterRedaction = false;
|
|
8033
|
+
let rawCandidateCount = 0;
|
|
8034
|
+
let validCandidateCount = 0;
|
|
8006
8035
|
const callerOnExhaustedEmpty = options.extract.onExhaustedEmpty;
|
|
8007
8036
|
const callerOnCandidatesDropped = options.extract.onCandidatesDropped;
|
|
8037
|
+
const callerOnCandidatesParsed = options.extract.onCandidatesParsed;
|
|
8038
|
+
const tExtract = Date.now();
|
|
8008
8039
|
const candidates = await extractFacts(messages, {
|
|
8009
8040
|
...options.extract,
|
|
8010
8041
|
onExhaustedEmpty: (failure) => {
|
|
@@ -8015,8 +8046,14 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
8015
8046
|
onCandidatesDropped: () => {
|
|
8016
8047
|
droppedAfterRedaction = true;
|
|
8017
8048
|
callerOnCandidatesDropped?.();
|
|
8049
|
+
},
|
|
8050
|
+
onCandidatesParsed: (stats) => {
|
|
8051
|
+
rawCandidateCount = stats.rawCount;
|
|
8052
|
+
validCandidateCount = stats.validCount;
|
|
8053
|
+
callerOnCandidatesParsed?.(stats);
|
|
8018
8054
|
}
|
|
8019
8055
|
});
|
|
8056
|
+
const extractMs = Date.now() - tExtract;
|
|
8020
8057
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
8021
8058
|
const log = getLogger();
|
|
8022
8059
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -8064,6 +8101,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
8064
8101
|
const results = [];
|
|
8065
8102
|
const quarantinedInfo = [];
|
|
8066
8103
|
let failedWrites = 0;
|
|
8104
|
+
const tRetain = Date.now();
|
|
8067
8105
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
8068
8106
|
try {
|
|
8069
8107
|
const result = await retain(candidate.content, retainCtx, {
|
|
@@ -8130,6 +8168,21 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
8130
8168
|
failedCount: failedWrites,
|
|
8131
8169
|
outcome,
|
|
8132
8170
|
quarantined: quarantinedInfo,
|
|
8171
|
+
funnel: {
|
|
8172
|
+
rawCandidateCount,
|
|
8173
|
+
validCandidateCount,
|
|
8174
|
+
afterRedactionCount: candidates.length,
|
|
8175
|
+
aboveConfidenceCount: filtered.length,
|
|
8176
|
+
// The PERSISTED quarantines (`quarantinedInfo`), not the screened list: a
|
|
8177
|
+
// screened candidate whose retain() throws is counted in `failedCount`,
|
|
8178
|
+
// and counting it here too would double it and break the identity below.
|
|
8179
|
+
// This also keeps the count equal to `quarantined.length` on the result.
|
|
8180
|
+
quarantinedCount: quarantinedInfo.length,
|
|
8181
|
+
retainedCount: results.length,
|
|
8182
|
+
failedCount: failedWrites
|
|
8183
|
+
},
|
|
8184
|
+
timings: { extractMs, retainMs: Date.now() - tRetain },
|
|
8185
|
+
model: options.extract.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
8133
8186
|
// Only meaningful alongside `outcome: "empty-after-retry"`. Returned as well
|
|
8134
8187
|
// as pushed through the callback so a consumer that only inspects the result
|
|
8135
8188
|
// (rather than wiring a hook) can still report WHY.
|
|
@@ -8383,27 +8436,23 @@ function createAutoExtractor(options) {
|
|
|
8383
8436
|
const t0 = Date.now();
|
|
8384
8437
|
void (async () => {
|
|
8385
8438
|
try {
|
|
8386
|
-
const { candidates, results, failedCount, outcome, failure } = await extractAndRetain(
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
{
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
},
|
|
8402
|
-
...options.onMemoryQuarantined && {
|
|
8403
|
-
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
8404
|
-
}
|
|
8439
|
+
const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
8440
|
+
extract,
|
|
8441
|
+
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
8442
|
+
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
8443
|
+
...options.scope !== void 0 && { scope: options.scope },
|
|
8444
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
8445
|
+
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
8446
|
+
...injectionClassifierOptions !== void 0 && {
|
|
8447
|
+
injectionClassifier: injectionClassifierOptions
|
|
8448
|
+
},
|
|
8449
|
+
...options.onCandidateFailed && {
|
|
8450
|
+
onCandidateFailed: (candidate, error) => options.onCandidateFailed?.({ candidate, error, conversationId })
|
|
8451
|
+
},
|
|
8452
|
+
...options.onMemoryQuarantined && {
|
|
8453
|
+
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
8405
8454
|
}
|
|
8406
|
-
);
|
|
8455
|
+
});
|
|
8407
8456
|
if (outcome !== "empty-after-retry") {
|
|
8408
8457
|
const advancedTo = window2[window2.length - 1].id;
|
|
8409
8458
|
stateFor(conversationId).watermark = advancedTo;
|
|
@@ -8424,6 +8473,9 @@ function createAutoExtractor(options) {
|
|
|
8424
8473
|
durationMs: Date.now() - t0,
|
|
8425
8474
|
conversationId,
|
|
8426
8475
|
outcome,
|
|
8476
|
+
funnel,
|
|
8477
|
+
timings,
|
|
8478
|
+
model,
|
|
8427
8479
|
// Only set alongside `outcome: "empty-after-retry"`. Spread so the key
|
|
8428
8480
|
// is absent rather than explicitly undefined on a healthy turn —
|
|
8429
8481
|
// analytics backends store an explicit undefined as a real value.
|
|
@@ -20927,7 +20927,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
20927
20927
|
subQueries = decomp.subQueries;
|
|
20928
20928
|
}
|
|
20929
20929
|
}
|
|
20930
|
-
const { recall: recall2 } = await import("./recall-
|
|
20930
|
+
const { recall: recall2 } = await import("./recall-HA4UX4BB.mjs");
|
|
20931
20931
|
let recallDegraded = [];
|
|
20932
20932
|
const result = await recall2(
|
|
20933
20933
|
query,
|
|
@@ -21518,7 +21518,22 @@ async function recall(query, ctx, options = {}) {
|
|
|
21518
21518
|
let factLaneRankedOnCosine = false;
|
|
21519
21519
|
let decryptLastRan;
|
|
21520
21520
|
let vaultRowsDecrypted;
|
|
21521
|
-
|
|
21521
|
+
let graphLaneCount = 0;
|
|
21522
|
+
let temporalLaneCount = 0;
|
|
21523
|
+
let graphLaneFailed = false;
|
|
21524
|
+
let temporalLaneFailed = false;
|
|
21525
|
+
let hitLimit = false;
|
|
21526
|
+
let factFloor = -1;
|
|
21527
|
+
let chunkFloor = -1;
|
|
21528
|
+
const emptyReasonFor = (admitted, laneRan) => {
|
|
21529
|
+
if (admitted > 0) return "";
|
|
21530
|
+
if (!query || typeof query !== "string" || query.trim().length === 0) return "empty-query";
|
|
21531
|
+
if (!laneRan) return "no-lanes";
|
|
21532
|
+
const chunkLaneCouldAnswer = types.includes("chunk") && !!ctx.storageCtx;
|
|
21533
|
+
if (vaultSize === 0 && !chunkLaneCouldAnswer) return "vault-empty";
|
|
21534
|
+
return "no-candidates";
|
|
21535
|
+
};
|
|
21536
|
+
const emitDiagnostics = (candidateCount, admitted) => {
|
|
21522
21537
|
const cb = options.onDiagnostics;
|
|
21523
21538
|
if (!cb) return;
|
|
21524
21539
|
const degraded = [];
|
|
@@ -21529,6 +21544,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
21529
21544
|
degraded.push("decompose-moved");
|
|
21530
21545
|
}
|
|
21531
21546
|
if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
|
|
21547
|
+
if (graphLaneFailed) degraded.push("graph-lane-failed");
|
|
21548
|
+
if (temporalLaneFailed) degraded.push("temporal-lane-failed");
|
|
21549
|
+
const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx;
|
|
21550
|
+
const scores = admitted.map((m) => m.score);
|
|
21551
|
+
const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
|
|
21532
21552
|
const diagnostics = {
|
|
21533
21553
|
usedBudget,
|
|
21534
21554
|
reranked: didRerank,
|
|
@@ -21539,6 +21559,14 @@ async function recall(query, ctx, options = {}) {
|
|
|
21539
21559
|
...vaultRowsEmbedded !== void 0 && { vaultRowsEmbedded },
|
|
21540
21560
|
factCount: factResults.length,
|
|
21541
21561
|
chunkCount: chunkResults.length,
|
|
21562
|
+
admittedCount: admitted.length,
|
|
21563
|
+
topScore: scores.length > 0 ? Math.max(...scores) : -1,
|
|
21564
|
+
lowestAdmittedScore: scores.length > 0 ? Math.min(...scores) : -1,
|
|
21565
|
+
minScoreApplied,
|
|
21566
|
+
truncated: hitLimit,
|
|
21567
|
+
graphLaneCount,
|
|
21568
|
+
temporalLaneCount,
|
|
21569
|
+
emptyReason: emptyReasonFor(admitted.length, laneRan),
|
|
21542
21570
|
timings: {
|
|
21543
21571
|
total: nowMs2() - t0,
|
|
21544
21572
|
prep: prepMs,
|
|
@@ -21556,7 +21584,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21556
21584
|
}
|
|
21557
21585
|
};
|
|
21558
21586
|
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
21559
|
-
emitDiagnostics(0);
|
|
21587
|
+
emitDiagnostics(0, []);
|
|
21560
21588
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
21561
21589
|
}
|
|
21562
21590
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
@@ -21590,6 +21618,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21590
21618
|
// empty ranking instead (mirrors safeCountVault's fail-soft posture).
|
|
21591
21619
|
safeLane(
|
|
21592
21620
|
"graph",
|
|
21621
|
+
() => graphLaneFailed = true,
|
|
21593
21622
|
() => buildGraphLaneRanking(query, ctx, flags.traverse, {
|
|
21594
21623
|
...options.maxHops !== void 0 && { maxHops: options.maxHops },
|
|
21595
21624
|
...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
|
|
@@ -21598,12 +21627,19 @@ async function recall(query, ctx, options = {}) {
|
|
|
21598
21627
|
...graphRefiner && { refineNeighbors: graphRefiner }
|
|
21599
21628
|
})
|
|
21600
21629
|
),
|
|
21601
|
-
wantsTemporal ? safeLane(
|
|
21630
|
+
wantsTemporal ? safeLane(
|
|
21631
|
+
"temporal",
|
|
21632
|
+
() => temporalLaneFailed = true,
|
|
21633
|
+
() => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
|
|
21634
|
+
) : Promise.resolve([])
|
|
21602
21635
|
]);
|
|
21603
21636
|
prepMs = nowMs2() - prepStart;
|
|
21637
|
+
graphLaneCount = entityRanking.length;
|
|
21638
|
+
temporalLaneCount = temporalRanking.length;
|
|
21604
21639
|
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
21605
21640
|
const factStart = nowMs2();
|
|
21606
21641
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
21642
|
+
factFloor = vaultMinScore;
|
|
21607
21643
|
const {
|
|
21608
21644
|
results,
|
|
21609
21645
|
vaultSize: size,
|
|
@@ -21683,6 +21719,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21683
21719
|
if (types.includes("chunk") && ctx.storageCtx && queryEmbedding) {
|
|
21684
21720
|
const chunkStart = nowMs2();
|
|
21685
21721
|
const chunkMinScore = options.minScore ?? DEFAULT_CHUNK_MIN_SCORE;
|
|
21722
|
+
chunkFloor = chunkMinScore;
|
|
21686
21723
|
const results = await searchChunksOp(ctx.storageCtx, queryEmbedding, {
|
|
21687
21724
|
limit: types.includes("fact") ? Math.max(limit * 2, 16) : limit,
|
|
21688
21725
|
minSimilarity: chunkMinScore,
|
|
@@ -21709,9 +21746,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
21709
21746
|
memories2.sort((a, b) => b.score - a.score);
|
|
21710
21747
|
const candidateCount = factResults.length + chunkResults.length;
|
|
21711
21748
|
fuseMs = nowMs2() - fuseStart;
|
|
21712
|
-
|
|
21749
|
+
const admitted = memories2.slice(0, limit);
|
|
21750
|
+
hitLimit = memories2.length > limit;
|
|
21751
|
+
emitDiagnostics(candidateCount, admitted);
|
|
21713
21752
|
return {
|
|
21714
|
-
memories:
|
|
21753
|
+
memories: admitted,
|
|
21715
21754
|
usedBudget,
|
|
21716
21755
|
reranked: didRerank,
|
|
21717
21756
|
candidateCount,
|
|
@@ -21741,12 +21780,16 @@ async function recall(query, ctx, options = {}) {
|
|
|
21741
21780
|
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
21742
21781
|
const selectWith = (suppressed2) => {
|
|
21743
21782
|
const out = [];
|
|
21783
|
+
let cut = false;
|
|
21744
21784
|
for (const m of ordered) {
|
|
21745
|
-
if (out.length >= limit) break;
|
|
21746
21785
|
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
21786
|
+
if (out.length >= limit) {
|
|
21787
|
+
cut = true;
|
|
21788
|
+
break;
|
|
21789
|
+
}
|
|
21747
21790
|
out.push(m);
|
|
21748
21791
|
}
|
|
21749
|
-
return out;
|
|
21792
|
+
return { out, cut };
|
|
21750
21793
|
};
|
|
21751
21794
|
const provenanceOf = (selected) => {
|
|
21752
21795
|
const s = /* @__PURE__ */ new Set();
|
|
@@ -21756,15 +21799,18 @@ async function recall(query, ctx, options = {}) {
|
|
|
21756
21799
|
return s;
|
|
21757
21800
|
};
|
|
21758
21801
|
let suppressed = /* @__PURE__ */ new Set();
|
|
21759
|
-
let
|
|
21802
|
+
let selection = selectWith(suppressed);
|
|
21803
|
+
let memories = selection.out;
|
|
21760
21804
|
for (let i = 0; i < ordered.length; i++) {
|
|
21761
21805
|
const next = provenanceOf(memories);
|
|
21762
21806
|
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
21763
21807
|
suppressed = next;
|
|
21764
|
-
|
|
21808
|
+
selection = selectWith(suppressed);
|
|
21809
|
+
memories = selection.out;
|
|
21765
21810
|
}
|
|
21811
|
+
hitLimit = selection.cut;
|
|
21766
21812
|
fuseMs = nowMs2() - fuseStart;
|
|
21767
|
-
emitDiagnostics(byId.size);
|
|
21813
|
+
emitDiagnostics(byId.size, memories);
|
|
21768
21814
|
return {
|
|
21769
21815
|
memories,
|
|
21770
21816
|
usedBudget,
|
|
@@ -21848,10 +21894,11 @@ async function safeCountVault(ctx) {
|
|
|
21848
21894
|
return void 0;
|
|
21849
21895
|
}
|
|
21850
21896
|
}
|
|
21851
|
-
async function safeLane(label, run) {
|
|
21897
|
+
async function safeLane(label, onFailure, run) {
|
|
21852
21898
|
try {
|
|
21853
21899
|
return await run();
|
|
21854
21900
|
} catch (err) {
|
|
21901
|
+
onFailure();
|
|
21855
21902
|
getLogger().warn(
|
|
21856
21903
|
`[memory/recall] ${label} lane failed; continuing without it: ${err instanceof Error ? err.message : String(err)}`
|
|
21857
21904
|
);
|