@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/server/index.cjs
CHANGED
|
@@ -21668,7 +21668,22 @@ async function recall(query, ctx, options = {}) {
|
|
|
21668
21668
|
let factLaneRankedOnCosine = false;
|
|
21669
21669
|
let decryptLastRan;
|
|
21670
21670
|
let vaultRowsDecrypted;
|
|
21671
|
-
|
|
21671
|
+
let graphLaneCount = 0;
|
|
21672
|
+
let temporalLaneCount = 0;
|
|
21673
|
+
let graphLaneFailed = false;
|
|
21674
|
+
let temporalLaneFailed = false;
|
|
21675
|
+
let hitLimit = false;
|
|
21676
|
+
let factFloor = -1;
|
|
21677
|
+
let chunkFloor = -1;
|
|
21678
|
+
const emptyReasonFor = (admitted, laneRan) => {
|
|
21679
|
+
if (admitted > 0) return "";
|
|
21680
|
+
if (!query || typeof query !== "string" || query.trim().length === 0) return "empty-query";
|
|
21681
|
+
if (!laneRan) return "no-lanes";
|
|
21682
|
+
const chunkLaneCouldAnswer = types.includes("chunk") && !!ctx.storageCtx;
|
|
21683
|
+
if (vaultSize === 0 && !chunkLaneCouldAnswer) return "vault-empty";
|
|
21684
|
+
return "no-candidates";
|
|
21685
|
+
};
|
|
21686
|
+
const emitDiagnostics = (candidateCount, admitted) => {
|
|
21672
21687
|
const cb = options.onDiagnostics;
|
|
21673
21688
|
if (!cb) return;
|
|
21674
21689
|
const degraded = [];
|
|
@@ -21679,6 +21694,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
21679
21694
|
degraded.push("decompose-moved");
|
|
21680
21695
|
}
|
|
21681
21696
|
if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
|
|
21697
|
+
if (graphLaneFailed) degraded.push("graph-lane-failed");
|
|
21698
|
+
if (temporalLaneFailed) degraded.push("temporal-lane-failed");
|
|
21699
|
+
const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx;
|
|
21700
|
+
const scores = admitted.map((m) => m.score);
|
|
21701
|
+
const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
|
|
21682
21702
|
const diagnostics = {
|
|
21683
21703
|
usedBudget,
|
|
21684
21704
|
reranked: didRerank,
|
|
@@ -21689,6 +21709,14 @@ async function recall(query, ctx, options = {}) {
|
|
|
21689
21709
|
...vaultRowsEmbedded !== void 0 && { vaultRowsEmbedded },
|
|
21690
21710
|
factCount: factResults.length,
|
|
21691
21711
|
chunkCount: chunkResults.length,
|
|
21712
|
+
admittedCount: admitted.length,
|
|
21713
|
+
topScore: scores.length > 0 ? Math.max(...scores) : -1,
|
|
21714
|
+
lowestAdmittedScore: scores.length > 0 ? Math.min(...scores) : -1,
|
|
21715
|
+
minScoreApplied,
|
|
21716
|
+
truncated: hitLimit,
|
|
21717
|
+
graphLaneCount,
|
|
21718
|
+
temporalLaneCount,
|
|
21719
|
+
emptyReason: emptyReasonFor(admitted.length, laneRan),
|
|
21692
21720
|
timings: {
|
|
21693
21721
|
total: nowMs() - t0,
|
|
21694
21722
|
prep: prepMs,
|
|
@@ -21706,7 +21734,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21706
21734
|
}
|
|
21707
21735
|
};
|
|
21708
21736
|
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
21709
|
-
emitDiagnostics(0);
|
|
21737
|
+
emitDiagnostics(0, []);
|
|
21710
21738
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
21711
21739
|
}
|
|
21712
21740
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
@@ -21740,6 +21768,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21740
21768
|
// empty ranking instead (mirrors safeCountVault's fail-soft posture).
|
|
21741
21769
|
safeLane(
|
|
21742
21770
|
"graph",
|
|
21771
|
+
() => graphLaneFailed = true,
|
|
21743
21772
|
() => buildGraphLaneRanking(query, ctx, flags.traverse, {
|
|
21744
21773
|
...options.maxHops !== void 0 && { maxHops: options.maxHops },
|
|
21745
21774
|
...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
|
|
@@ -21748,12 +21777,19 @@ async function recall(query, ctx, options = {}) {
|
|
|
21748
21777
|
...graphRefiner && { refineNeighbors: graphRefiner }
|
|
21749
21778
|
})
|
|
21750
21779
|
),
|
|
21751
|
-
wantsTemporal ? safeLane(
|
|
21780
|
+
wantsTemporal ? safeLane(
|
|
21781
|
+
"temporal",
|
|
21782
|
+
() => temporalLaneFailed = true,
|
|
21783
|
+
() => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
|
|
21784
|
+
) : Promise.resolve([])
|
|
21752
21785
|
]);
|
|
21753
21786
|
prepMs = nowMs() - prepStart;
|
|
21787
|
+
graphLaneCount = entityRanking.length;
|
|
21788
|
+
temporalLaneCount = temporalRanking.length;
|
|
21754
21789
|
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
21755
21790
|
const factStart = nowMs();
|
|
21756
21791
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
21792
|
+
factFloor = vaultMinScore;
|
|
21757
21793
|
const {
|
|
21758
21794
|
results,
|
|
21759
21795
|
vaultSize: size,
|
|
@@ -21833,6 +21869,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
21833
21869
|
if (types.includes("chunk") && ctx.storageCtx && queryEmbedding) {
|
|
21834
21870
|
const chunkStart = nowMs();
|
|
21835
21871
|
const chunkMinScore = options.minScore ?? DEFAULT_CHUNK_MIN_SCORE;
|
|
21872
|
+
chunkFloor = chunkMinScore;
|
|
21836
21873
|
const results = await searchChunksOp(ctx.storageCtx, queryEmbedding, {
|
|
21837
21874
|
limit: types.includes("fact") ? Math.max(limit * 2, 16) : limit,
|
|
21838
21875
|
minSimilarity: chunkMinScore,
|
|
@@ -21859,9 +21896,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
21859
21896
|
memories2.sort((a, b) => b.score - a.score);
|
|
21860
21897
|
const candidateCount = factResults.length + chunkResults.length;
|
|
21861
21898
|
fuseMs = nowMs() - fuseStart;
|
|
21862
|
-
|
|
21899
|
+
const admitted = memories2.slice(0, limit);
|
|
21900
|
+
hitLimit = memories2.length > limit;
|
|
21901
|
+
emitDiagnostics(candidateCount, admitted);
|
|
21863
21902
|
return {
|
|
21864
|
-
memories:
|
|
21903
|
+
memories: admitted,
|
|
21865
21904
|
usedBudget,
|
|
21866
21905
|
reranked: didRerank,
|
|
21867
21906
|
candidateCount,
|
|
@@ -21891,12 +21930,16 @@ async function recall(query, ctx, options = {}) {
|
|
|
21891
21930
|
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
21892
21931
|
const selectWith = (suppressed2) => {
|
|
21893
21932
|
const out = [];
|
|
21933
|
+
let cut = false;
|
|
21894
21934
|
for (const m of ordered) {
|
|
21895
|
-
if (out.length >= limit) break;
|
|
21896
21935
|
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
21936
|
+
if (out.length >= limit) {
|
|
21937
|
+
cut = true;
|
|
21938
|
+
break;
|
|
21939
|
+
}
|
|
21897
21940
|
out.push(m);
|
|
21898
21941
|
}
|
|
21899
|
-
return out;
|
|
21942
|
+
return { out, cut };
|
|
21900
21943
|
};
|
|
21901
21944
|
const provenanceOf = (selected) => {
|
|
21902
21945
|
const s = /* @__PURE__ */ new Set();
|
|
@@ -21906,15 +21949,18 @@ async function recall(query, ctx, options = {}) {
|
|
|
21906
21949
|
return s;
|
|
21907
21950
|
};
|
|
21908
21951
|
let suppressed = /* @__PURE__ */ new Set();
|
|
21909
|
-
let
|
|
21952
|
+
let selection = selectWith(suppressed);
|
|
21953
|
+
let memories = selection.out;
|
|
21910
21954
|
for (let i = 0; i < ordered.length; i++) {
|
|
21911
21955
|
const next = provenanceOf(memories);
|
|
21912
21956
|
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
21913
21957
|
suppressed = next;
|
|
21914
|
-
|
|
21958
|
+
selection = selectWith(suppressed);
|
|
21959
|
+
memories = selection.out;
|
|
21915
21960
|
}
|
|
21961
|
+
hitLimit = selection.cut;
|
|
21916
21962
|
fuseMs = nowMs() - fuseStart;
|
|
21917
|
-
emitDiagnostics(byId.size);
|
|
21963
|
+
emitDiagnostics(byId.size, memories);
|
|
21918
21964
|
return {
|
|
21919
21965
|
memories,
|
|
21920
21966
|
usedBudget,
|
|
@@ -21998,10 +22044,11 @@ async function safeCountVault(ctx) {
|
|
|
21998
22044
|
return void 0;
|
|
21999
22045
|
}
|
|
22000
22046
|
}
|
|
22001
|
-
async function safeLane(label, run) {
|
|
22047
|
+
async function safeLane(label, onFailure, run) {
|
|
22002
22048
|
try {
|
|
22003
22049
|
return await run();
|
|
22004
22050
|
} catch (err) {
|
|
22051
|
+
onFailure();
|
|
22005
22052
|
getLogger().warn(
|
|
22006
22053
|
`[memory/recall] ${label} lane failed; continuing without it: ${err instanceof Error ? err.message : String(err)}`
|
|
22007
22054
|
);
|
|
@@ -29296,6 +29343,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
29296
29343
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
29297
29344
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
29298
29345
|
let supersedeTargetIds = [];
|
|
29346
|
+
let consolidationDecidedCreate = false;
|
|
29299
29347
|
let supersedeContent;
|
|
29300
29348
|
let prepared;
|
|
29301
29349
|
if (enableAutoMerge) {
|
|
@@ -29323,8 +29371,12 @@ async function retain(content, ctx, options = {}) {
|
|
|
29323
29371
|
const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
|
|
29324
29372
|
if (outcome) {
|
|
29325
29373
|
if ("done" in outcome) return outcome.done;
|
|
29326
|
-
|
|
29327
|
-
|
|
29374
|
+
if ("create" in outcome) {
|
|
29375
|
+
consolidationDecidedCreate = true;
|
|
29376
|
+
} else {
|
|
29377
|
+
supersedeTargetIds = outcome.supersede;
|
|
29378
|
+
supersedeContent = outcome.content;
|
|
29379
|
+
}
|
|
29328
29380
|
}
|
|
29329
29381
|
}
|
|
29330
29382
|
if (supersedeTargetIds.length === 0) {
|
|
@@ -29374,7 +29426,14 @@ async function retain(content, ctx, options = {}) {
|
|
|
29374
29426
|
action: "merge",
|
|
29375
29427
|
memoryId: targetId,
|
|
29376
29428
|
targetId,
|
|
29377
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
29429
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
29430
|
+
similarity: matches[0].similarity,
|
|
29431
|
+
// Stage 1 may have run and explicitly said `create`, and Stage 2
|
|
29432
|
+
// then found a strict-cosine match anyway. Reporting the decision
|
|
29433
|
+
// here is what makes that DISAGREEMENT visible — without it the
|
|
29434
|
+
// model's create silently vanished from the distribution whenever
|
|
29435
|
+
// the cosine stage won.
|
|
29436
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
29378
29437
|
};
|
|
29379
29438
|
}
|
|
29380
29439
|
await assertMergeTargetGoneOrThrow(ctx, targetId);
|
|
@@ -29387,12 +29446,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
29387
29446
|
const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
|
|
29388
29447
|
const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
29389
29448
|
if (options.respectTombstones) {
|
|
29390
|
-
const
|
|
29449
|
+
const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
|
|
29391
29450
|
threshold,
|
|
29392
29451
|
folderId: options.folderId
|
|
29393
29452
|
});
|
|
29394
|
-
if (
|
|
29395
|
-
return {
|
|
29453
|
+
if (tombstone) {
|
|
29454
|
+
return {
|
|
29455
|
+
action: "suppressed",
|
|
29456
|
+
memoryId: tombstone.id,
|
|
29457
|
+
tombstoneId: tombstone.id,
|
|
29458
|
+
proofCount: 0,
|
|
29459
|
+
similarity: tombstone.similarity
|
|
29460
|
+
};
|
|
29396
29461
|
}
|
|
29397
29462
|
}
|
|
29398
29463
|
const createOpts = {
|
|
@@ -29459,7 +29524,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
29459
29524
|
action: "supersede",
|
|
29460
29525
|
memoryId: created2.uniqueId,
|
|
29461
29526
|
targetId: primaryTargetId,
|
|
29462
|
-
proofCount: 1
|
|
29527
|
+
proofCount: 1,
|
|
29528
|
+
consolidation: "supersede"
|
|
29463
29529
|
};
|
|
29464
29530
|
}
|
|
29465
29531
|
notifyConsolidationFallback(
|
|
@@ -29473,7 +29539,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
29473
29539
|
return {
|
|
29474
29540
|
action: "create",
|
|
29475
29541
|
memoryId: created.uniqueId,
|
|
29476
|
-
proofCount: 1
|
|
29542
|
+
proofCount: 1,
|
|
29543
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
29477
29544
|
};
|
|
29478
29545
|
}
|
|
29479
29546
|
function unionStrings(a, b) {
|
|
@@ -29503,7 +29570,7 @@ async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
|
|
|
29503
29570
|
bestId = row.uniqueId;
|
|
29504
29571
|
}
|
|
29505
29572
|
}
|
|
29506
|
-
return bestId;
|
|
29573
|
+
return bestId === null ? null : { id: bestId, similarity: bestSim };
|
|
29507
29574
|
}
|
|
29508
29575
|
function pickEventTimeUpdate(existing, incoming) {
|
|
29509
29576
|
if (incoming === void 0 || incoming === null) return void 0;
|
|
@@ -29545,7 +29612,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
29545
29612
|
}));
|
|
29546
29613
|
const { consolidateMemory: doConsolidate } = await Promise.resolve().then(() => (init_consolidate(), consolidate_exports));
|
|
29547
29614
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
29548
|
-
if (decision.action === "create") return null;
|
|
29615
|
+
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
29549
29616
|
if (decision.action === "supersede" && decision.content) {
|
|
29550
29617
|
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
29551
29618
|
if (requestedIds.length === 0) return null;
|
|
@@ -29604,7 +29671,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
29604
29671
|
action: "merge",
|
|
29605
29672
|
memoryId: decision.targetId,
|
|
29606
29673
|
targetId: decision.targetId,
|
|
29607
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
29674
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
29675
|
+
consolidation: "noop"
|
|
29608
29676
|
}
|
|
29609
29677
|
};
|
|
29610
29678
|
}
|
|
@@ -29657,7 +29725,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
29657
29725
|
action: "update",
|
|
29658
29726
|
memoryId: decision.targetId,
|
|
29659
29727
|
targetId: decision.targetId,
|
|
29660
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
29728
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
29729
|
+
consolidation: "update"
|
|
29661
29730
|
}
|
|
29662
29731
|
};
|
|
29663
29732
|
}
|
|
@@ -29799,6 +29868,11 @@ Extract durable user facts.`,
|
|
|
29799
29868
|
fallbackSourceId,
|
|
29800
29869
|
options.userIdentity ?? []
|
|
29801
29870
|
);
|
|
29871
|
+
const rawCandidates = parsed.candidates;
|
|
29872
|
+
options.onCandidatesParsed?.({
|
|
29873
|
+
rawCount: Array.isArray(rawCandidates) ? rawCandidates.length : 0,
|
|
29874
|
+
validCount: candidates.length
|
|
29875
|
+
});
|
|
29802
29876
|
if (!redactor) return candidates;
|
|
29803
29877
|
const restored = restoreCandidates(candidates, redactor, options.userIdentity ?? []);
|
|
29804
29878
|
if (candidates.length > 0 && restored.length === 0) {
|
|
@@ -29835,8 +29909,12 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
29835
29909
|
let exhaustedEmpty = false;
|
|
29836
29910
|
let exhaustedFailure;
|
|
29837
29911
|
let droppedAfterRedaction = false;
|
|
29912
|
+
let rawCandidateCount = 0;
|
|
29913
|
+
let validCandidateCount = 0;
|
|
29838
29914
|
const callerOnExhaustedEmpty = options.extract.onExhaustedEmpty;
|
|
29839
29915
|
const callerOnCandidatesDropped = options.extract.onCandidatesDropped;
|
|
29916
|
+
const callerOnCandidatesParsed = options.extract.onCandidatesParsed;
|
|
29917
|
+
const tExtract = Date.now();
|
|
29840
29918
|
const candidates = await extractFacts(messages, {
|
|
29841
29919
|
...options.extract,
|
|
29842
29920
|
onExhaustedEmpty: (failure) => {
|
|
@@ -29847,8 +29925,14 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
29847
29925
|
onCandidatesDropped: () => {
|
|
29848
29926
|
droppedAfterRedaction = true;
|
|
29849
29927
|
callerOnCandidatesDropped?.();
|
|
29928
|
+
},
|
|
29929
|
+
onCandidatesParsed: (stats) => {
|
|
29930
|
+
rawCandidateCount = stats.rawCount;
|
|
29931
|
+
validCandidateCount = stats.validCount;
|
|
29932
|
+
callerOnCandidatesParsed?.(stats);
|
|
29850
29933
|
}
|
|
29851
29934
|
});
|
|
29935
|
+
const extractMs = Date.now() - tExtract;
|
|
29852
29936
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
29853
29937
|
const log = getLogger();
|
|
29854
29938
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -29896,6 +29980,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
29896
29980
|
const results = [];
|
|
29897
29981
|
const quarantinedInfo = [];
|
|
29898
29982
|
let failedWrites = 0;
|
|
29983
|
+
const tRetain = Date.now();
|
|
29899
29984
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
29900
29985
|
try {
|
|
29901
29986
|
const result = await retain(candidate.content, retainCtx, {
|
|
@@ -29962,6 +30047,21 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
29962
30047
|
failedCount: failedWrites,
|
|
29963
30048
|
outcome,
|
|
29964
30049
|
quarantined: quarantinedInfo,
|
|
30050
|
+
funnel: {
|
|
30051
|
+
rawCandidateCount,
|
|
30052
|
+
validCandidateCount,
|
|
30053
|
+
afterRedactionCount: candidates.length,
|
|
30054
|
+
aboveConfidenceCount: filtered.length,
|
|
30055
|
+
// The PERSISTED quarantines (`quarantinedInfo`), not the screened list: a
|
|
30056
|
+
// screened candidate whose retain() throws is counted in `failedCount`,
|
|
30057
|
+
// and counting it here too would double it and break the identity below.
|
|
30058
|
+
// This also keeps the count equal to `quarantined.length` on the result.
|
|
30059
|
+
quarantinedCount: quarantinedInfo.length,
|
|
30060
|
+
retainedCount: results.length,
|
|
30061
|
+
failedCount: failedWrites
|
|
30062
|
+
},
|
|
30063
|
+
timings: { extractMs, retainMs: Date.now() - tRetain },
|
|
30064
|
+
model: options.extract.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
29965
30065
|
// Only meaningful alongside `outcome: "empty-after-retry"`. Returned as well
|
|
29966
30066
|
// as pushed through the callback so a consumer that only inspects the result
|
|
29967
30067
|
// (rather than wiring a hook) can still report WHY.
|
|
@@ -30217,27 +30317,23 @@ function createAutoExtractor(options) {
|
|
|
30217
30317
|
const t0 = Date.now();
|
|
30218
30318
|
void (async () => {
|
|
30219
30319
|
try {
|
|
30220
|
-
const { candidates, results, failedCount, outcome, failure } = await extractAndRetain(
|
|
30221
|
-
|
|
30222
|
-
|
|
30223
|
-
{
|
|
30224
|
-
|
|
30225
|
-
|
|
30226
|
-
|
|
30227
|
-
|
|
30228
|
-
|
|
30229
|
-
|
|
30230
|
-
|
|
30231
|
-
|
|
30232
|
-
|
|
30233
|
-
|
|
30234
|
-
|
|
30235
|
-
},
|
|
30236
|
-
...options.onMemoryQuarantined && {
|
|
30237
|
-
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
30238
|
-
}
|
|
30320
|
+
const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
30321
|
+
extract,
|
|
30322
|
+
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
30323
|
+
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
30324
|
+
...options.scope !== void 0 && { scope: options.scope },
|
|
30325
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
30326
|
+
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
30327
|
+
...injectionClassifierOptions !== void 0 && {
|
|
30328
|
+
injectionClassifier: injectionClassifierOptions
|
|
30329
|
+
},
|
|
30330
|
+
...options.onCandidateFailed && {
|
|
30331
|
+
onCandidateFailed: (candidate, error) => options.onCandidateFailed?.({ candidate, error, conversationId })
|
|
30332
|
+
},
|
|
30333
|
+
...options.onMemoryQuarantined && {
|
|
30334
|
+
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
30239
30335
|
}
|
|
30240
|
-
);
|
|
30336
|
+
});
|
|
30241
30337
|
if (outcome !== "empty-after-retry") {
|
|
30242
30338
|
const advancedTo = window2[window2.length - 1].id;
|
|
30243
30339
|
stateFor(conversationId).watermark = advancedTo;
|
|
@@ -30258,6 +30354,9 @@ function createAutoExtractor(options) {
|
|
|
30258
30354
|
durationMs: Date.now() - t0,
|
|
30259
30355
|
conversationId,
|
|
30260
30356
|
outcome,
|
|
30357
|
+
funnel,
|
|
30358
|
+
timings,
|
|
30359
|
+
model,
|
|
30261
30360
|
// Only set alongside `outcome: "empty-after-retry"`. Spread so the key
|
|
30262
30361
|
// is absent rather than explicitly undefined on a healthy turn —
|
|
30263
30362
|
// analytics backends store an explicit undefined as a real value.
|