@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.cjs
CHANGED
|
@@ -7962,7 +7962,22 @@ async function recall(query, ctx, options = {}) {
|
|
|
7962
7962
|
let factLaneRankedOnCosine = false;
|
|
7963
7963
|
let decryptLastRan;
|
|
7964
7964
|
let vaultRowsDecrypted;
|
|
7965
|
-
|
|
7965
|
+
let graphLaneCount = 0;
|
|
7966
|
+
let temporalLaneCount = 0;
|
|
7967
|
+
let graphLaneFailed = false;
|
|
7968
|
+
let temporalLaneFailed = false;
|
|
7969
|
+
let hitLimit = false;
|
|
7970
|
+
let factFloor = -1;
|
|
7971
|
+
let chunkFloor = -1;
|
|
7972
|
+
const emptyReasonFor = (admitted, laneRan) => {
|
|
7973
|
+
if (admitted > 0) return "";
|
|
7974
|
+
if (!query || typeof query !== "string" || query.trim().length === 0) return "empty-query";
|
|
7975
|
+
if (!laneRan) return "no-lanes";
|
|
7976
|
+
const chunkLaneCouldAnswer = types.includes("chunk") && !!ctx.storageCtx;
|
|
7977
|
+
if (vaultSize === 0 && !chunkLaneCouldAnswer) return "vault-empty";
|
|
7978
|
+
return "no-candidates";
|
|
7979
|
+
};
|
|
7980
|
+
const emitDiagnostics = (candidateCount, admitted) => {
|
|
7966
7981
|
const cb = options.onDiagnostics;
|
|
7967
7982
|
if (!cb) return;
|
|
7968
7983
|
const degraded = [];
|
|
@@ -7973,6 +7988,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
7973
7988
|
degraded.push("decompose-moved");
|
|
7974
7989
|
}
|
|
7975
7990
|
if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
|
|
7991
|
+
if (graphLaneFailed) degraded.push("graph-lane-failed");
|
|
7992
|
+
if (temporalLaneFailed) degraded.push("temporal-lane-failed");
|
|
7993
|
+
const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx;
|
|
7994
|
+
const scores = admitted.map((m) => m.score);
|
|
7995
|
+
const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
|
|
7976
7996
|
const diagnostics = {
|
|
7977
7997
|
usedBudget,
|
|
7978
7998
|
reranked: didRerank,
|
|
@@ -7983,6 +8003,14 @@ async function recall(query, ctx, options = {}) {
|
|
|
7983
8003
|
...vaultRowsEmbedded !== void 0 && { vaultRowsEmbedded },
|
|
7984
8004
|
factCount: factResults.length,
|
|
7985
8005
|
chunkCount: chunkResults.length,
|
|
8006
|
+
admittedCount: admitted.length,
|
|
8007
|
+
topScore: scores.length > 0 ? Math.max(...scores) : -1,
|
|
8008
|
+
lowestAdmittedScore: scores.length > 0 ? Math.min(...scores) : -1,
|
|
8009
|
+
minScoreApplied,
|
|
8010
|
+
truncated: hitLimit,
|
|
8011
|
+
graphLaneCount,
|
|
8012
|
+
temporalLaneCount,
|
|
8013
|
+
emptyReason: emptyReasonFor(admitted.length, laneRan),
|
|
7986
8014
|
timings: {
|
|
7987
8015
|
total: nowMs() - t0,
|
|
7988
8016
|
prep: prepMs,
|
|
@@ -8000,7 +8028,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
8000
8028
|
}
|
|
8001
8029
|
};
|
|
8002
8030
|
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
8003
|
-
emitDiagnostics(0);
|
|
8031
|
+
emitDiagnostics(0, []);
|
|
8004
8032
|
return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
|
|
8005
8033
|
}
|
|
8006
8034
|
const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
|
|
@@ -8034,6 +8062,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
8034
8062
|
// empty ranking instead (mirrors safeCountVault's fail-soft posture).
|
|
8035
8063
|
safeLane(
|
|
8036
8064
|
"graph",
|
|
8065
|
+
() => graphLaneFailed = true,
|
|
8037
8066
|
() => buildGraphLaneRanking(query, ctx, flags.traverse, {
|
|
8038
8067
|
...options.maxHops !== void 0 && { maxHops: options.maxHops },
|
|
8039
8068
|
...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
|
|
@@ -8042,12 +8071,19 @@ async function recall(query, ctx, options = {}) {
|
|
|
8042
8071
|
...graphRefiner && { refineNeighbors: graphRefiner }
|
|
8043
8072
|
})
|
|
8044
8073
|
),
|
|
8045
|
-
wantsTemporal ? safeLane(
|
|
8074
|
+
wantsTemporal ? safeLane(
|
|
8075
|
+
"temporal",
|
|
8076
|
+
() => temporalLaneFailed = true,
|
|
8077
|
+
() => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
|
|
8078
|
+
) : Promise.resolve([])
|
|
8046
8079
|
]);
|
|
8047
8080
|
prepMs = nowMs() - prepStart;
|
|
8081
|
+
graphLaneCount = entityRanking.length;
|
|
8082
|
+
temporalLaneCount = temporalRanking.length;
|
|
8048
8083
|
if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
|
|
8049
8084
|
const factStart = nowMs();
|
|
8050
8085
|
const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
|
|
8086
|
+
factFloor = vaultMinScore;
|
|
8051
8087
|
const {
|
|
8052
8088
|
results,
|
|
8053
8089
|
vaultSize: size,
|
|
@@ -8127,6 +8163,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
8127
8163
|
if (types.includes("chunk") && ctx.storageCtx && queryEmbedding) {
|
|
8128
8164
|
const chunkStart = nowMs();
|
|
8129
8165
|
const chunkMinScore = options.minScore ?? DEFAULT_CHUNK_MIN_SCORE;
|
|
8166
|
+
chunkFloor = chunkMinScore;
|
|
8130
8167
|
const results = await searchChunksOp(ctx.storageCtx, queryEmbedding, {
|
|
8131
8168
|
limit: types.includes("fact") ? Math.max(limit * 2, 16) : limit,
|
|
8132
8169
|
minSimilarity: chunkMinScore,
|
|
@@ -8153,9 +8190,11 @@ async function recall(query, ctx, options = {}) {
|
|
|
8153
8190
|
memories2.sort((a, b) => b.score - a.score);
|
|
8154
8191
|
const candidateCount = factResults.length + chunkResults.length;
|
|
8155
8192
|
fuseMs = nowMs() - fuseStart;
|
|
8156
|
-
|
|
8193
|
+
const admitted = memories2.slice(0, limit);
|
|
8194
|
+
hitLimit = memories2.length > limit;
|
|
8195
|
+
emitDiagnostics(candidateCount, admitted);
|
|
8157
8196
|
return {
|
|
8158
|
-
memories:
|
|
8197
|
+
memories: admitted,
|
|
8159
8198
|
usedBudget,
|
|
8160
8199
|
reranked: didRerank,
|
|
8161
8200
|
candidateCount,
|
|
@@ -8185,12 +8224,16 @@ async function recall(query, ctx, options = {}) {
|
|
|
8185
8224
|
const ordered = [...byId.values()].sort((a, b) => b.score - a.score);
|
|
8186
8225
|
const selectWith = (suppressed2) => {
|
|
8187
8226
|
const out = [];
|
|
8227
|
+
let cut = false;
|
|
8188
8228
|
for (const m of ordered) {
|
|
8189
|
-
if (out.length >= limit) break;
|
|
8190
8229
|
if (m.kind === "chunk" && m.messageId && suppressed2.has(m.messageId)) continue;
|
|
8230
|
+
if (out.length >= limit) {
|
|
8231
|
+
cut = true;
|
|
8232
|
+
break;
|
|
8233
|
+
}
|
|
8191
8234
|
out.push(m);
|
|
8192
8235
|
}
|
|
8193
|
-
return out;
|
|
8236
|
+
return { out, cut };
|
|
8194
8237
|
};
|
|
8195
8238
|
const provenanceOf = (selected) => {
|
|
8196
8239
|
const s = /* @__PURE__ */ new Set();
|
|
@@ -8200,15 +8243,18 @@ async function recall(query, ctx, options = {}) {
|
|
|
8200
8243
|
return s;
|
|
8201
8244
|
};
|
|
8202
8245
|
let suppressed = /* @__PURE__ */ new Set();
|
|
8203
|
-
let
|
|
8246
|
+
let selection = selectWith(suppressed);
|
|
8247
|
+
let memories = selection.out;
|
|
8204
8248
|
for (let i = 0; i < ordered.length; i++) {
|
|
8205
8249
|
const next = provenanceOf(memories);
|
|
8206
8250
|
if (next.size === suppressed.size && [...next].every((id) => suppressed.has(id))) break;
|
|
8207
8251
|
suppressed = next;
|
|
8208
|
-
|
|
8252
|
+
selection = selectWith(suppressed);
|
|
8253
|
+
memories = selection.out;
|
|
8209
8254
|
}
|
|
8255
|
+
hitLimit = selection.cut;
|
|
8210
8256
|
fuseMs = nowMs() - fuseStart;
|
|
8211
|
-
emitDiagnostics(byId.size);
|
|
8257
|
+
emitDiagnostics(byId.size, memories);
|
|
8212
8258
|
return {
|
|
8213
8259
|
memories,
|
|
8214
8260
|
usedBudget,
|
|
@@ -8292,10 +8338,11 @@ async function safeCountVault(ctx) {
|
|
|
8292
8338
|
return void 0;
|
|
8293
8339
|
}
|
|
8294
8340
|
}
|
|
8295
|
-
async function safeLane(label, run) {
|
|
8341
|
+
async function safeLane(label, onFailure, run) {
|
|
8296
8342
|
try {
|
|
8297
8343
|
return await run();
|
|
8298
8344
|
} catch (err) {
|
|
8345
|
+
onFailure();
|
|
8299
8346
|
getLogger().warn(
|
|
8300
8347
|
`[memory/recall] ${label} lane failed; continuing without it: ${err instanceof Error ? err.message : String(err)}`
|
|
8301
8348
|
);
|
|
@@ -17683,6 +17730,7 @@ async function retain(content, ctx, options = {}) {
|
|
|
17683
17730
|
const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
|
|
17684
17731
|
const resolvedScope = options.scope ?? DEFAULT_SCOPE;
|
|
17685
17732
|
let supersedeTargetIds = [];
|
|
17733
|
+
let consolidationDecidedCreate = false;
|
|
17686
17734
|
let supersedeContent;
|
|
17687
17735
|
let prepared;
|
|
17688
17736
|
if (enableAutoMerge) {
|
|
@@ -17710,8 +17758,12 @@ async function retain(content, ctx, options = {}) {
|
|
|
17710
17758
|
const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
|
|
17711
17759
|
if (outcome) {
|
|
17712
17760
|
if ("done" in outcome) return outcome.done;
|
|
17713
|
-
|
|
17714
|
-
|
|
17761
|
+
if ("create" in outcome) {
|
|
17762
|
+
consolidationDecidedCreate = true;
|
|
17763
|
+
} else {
|
|
17764
|
+
supersedeTargetIds = outcome.supersede;
|
|
17765
|
+
supersedeContent = outcome.content;
|
|
17766
|
+
}
|
|
17715
17767
|
}
|
|
17716
17768
|
}
|
|
17717
17769
|
if (supersedeTargetIds.length === 0) {
|
|
@@ -17761,7 +17813,14 @@ async function retain(content, ctx, options = {}) {
|
|
|
17761
17813
|
action: "merge",
|
|
17762
17814
|
memoryId: targetId,
|
|
17763
17815
|
targetId,
|
|
17764
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
17816
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
17817
|
+
similarity: matches[0].similarity,
|
|
17818
|
+
// Stage 1 may have run and explicitly said `create`, and Stage 2
|
|
17819
|
+
// then found a strict-cosine match anyway. Reporting the decision
|
|
17820
|
+
// here is what makes that DISAGREEMENT visible — without it the
|
|
17821
|
+
// model's create silently vanished from the distribution whenever
|
|
17822
|
+
// the cosine stage won.
|
|
17823
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
17765
17824
|
};
|
|
17766
17825
|
}
|
|
17767
17826
|
await assertMergeTargetGoneOrThrow(ctx, targetId);
|
|
@@ -17774,12 +17833,18 @@ async function retain(content, ctx, options = {}) {
|
|
|
17774
17833
|
const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
|
|
17775
17834
|
const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
17776
17835
|
if (options.respectTombstones) {
|
|
17777
|
-
const
|
|
17836
|
+
const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
|
|
17778
17837
|
threshold,
|
|
17779
17838
|
folderId: options.folderId
|
|
17780
17839
|
});
|
|
17781
|
-
if (
|
|
17782
|
-
return {
|
|
17840
|
+
if (tombstone) {
|
|
17841
|
+
return {
|
|
17842
|
+
action: "suppressed",
|
|
17843
|
+
memoryId: tombstone.id,
|
|
17844
|
+
tombstoneId: tombstone.id,
|
|
17845
|
+
proofCount: 0,
|
|
17846
|
+
similarity: tombstone.similarity
|
|
17847
|
+
};
|
|
17783
17848
|
}
|
|
17784
17849
|
}
|
|
17785
17850
|
const createOpts = {
|
|
@@ -17846,7 +17911,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
17846
17911
|
action: "supersede",
|
|
17847
17912
|
memoryId: created2.uniqueId,
|
|
17848
17913
|
targetId: primaryTargetId,
|
|
17849
|
-
proofCount: 1
|
|
17914
|
+
proofCount: 1,
|
|
17915
|
+
consolidation: "supersede"
|
|
17850
17916
|
};
|
|
17851
17917
|
}
|
|
17852
17918
|
notifyConsolidationFallback(
|
|
@@ -17860,7 +17926,8 @@ async function retain(content, ctx, options = {}) {
|
|
|
17860
17926
|
return {
|
|
17861
17927
|
action: "create",
|
|
17862
17928
|
memoryId: created.uniqueId,
|
|
17863
|
-
proofCount: 1
|
|
17929
|
+
proofCount: 1,
|
|
17930
|
+
...consolidationDecidedCreate && { consolidation: "create" }
|
|
17864
17931
|
};
|
|
17865
17932
|
}
|
|
17866
17933
|
function unionStrings(a, b) {
|
|
@@ -17890,7 +17957,7 @@ async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
|
|
|
17890
17957
|
bestId = row.uniqueId;
|
|
17891
17958
|
}
|
|
17892
17959
|
}
|
|
17893
|
-
return bestId;
|
|
17960
|
+
return bestId === null ? null : { id: bestId, similarity: bestSim };
|
|
17894
17961
|
}
|
|
17895
17962
|
function pickEventTimeUpdate(existing, incoming) {
|
|
17896
17963
|
if (incoming === void 0 || incoming === null) return void 0;
|
|
@@ -17932,7 +17999,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17932
17999
|
}));
|
|
17933
18000
|
const { consolidateMemory: doConsolidate } = await Promise.resolve().then(() => (init_consolidate(), consolidate_exports));
|
|
17934
18001
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
17935
|
-
if (decision.action === "create") return null;
|
|
18002
|
+
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
17936
18003
|
if (decision.action === "supersede" && decision.content) {
|
|
17937
18004
|
const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
|
|
17938
18005
|
if (requestedIds.length === 0) return null;
|
|
@@ -17991,7 +18058,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
17991
18058
|
action: "merge",
|
|
17992
18059
|
memoryId: decision.targetId,
|
|
17993
18060
|
targetId: decision.targetId,
|
|
17994
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
18061
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
18062
|
+
consolidation: "noop"
|
|
17995
18063
|
}
|
|
17996
18064
|
};
|
|
17997
18065
|
}
|
|
@@ -18044,7 +18112,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
18044
18112
|
action: "update",
|
|
18045
18113
|
memoryId: decision.targetId,
|
|
18046
18114
|
targetId: decision.targetId,
|
|
18047
|
-
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1
|
|
18115
|
+
proofCount: updated.proofCount ?? (existing.proofCount ?? 1) + 1,
|
|
18116
|
+
consolidation: "update"
|
|
18048
18117
|
}
|
|
18049
18118
|
};
|
|
18050
18119
|
}
|
|
@@ -18186,6 +18255,11 @@ Extract durable user facts.`,
|
|
|
18186
18255
|
fallbackSourceId,
|
|
18187
18256
|
options.userIdentity ?? []
|
|
18188
18257
|
);
|
|
18258
|
+
const rawCandidates = parsed.candidates;
|
|
18259
|
+
options.onCandidatesParsed?.({
|
|
18260
|
+
rawCount: Array.isArray(rawCandidates) ? rawCandidates.length : 0,
|
|
18261
|
+
validCount: candidates.length
|
|
18262
|
+
});
|
|
18189
18263
|
if (!redactor) return candidates;
|
|
18190
18264
|
const restored = restoreCandidates(candidates, redactor, options.userIdentity ?? []);
|
|
18191
18265
|
if (candidates.length > 0 && restored.length === 0) {
|
|
@@ -18222,8 +18296,12 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18222
18296
|
let exhaustedEmpty = false;
|
|
18223
18297
|
let exhaustedFailure;
|
|
18224
18298
|
let droppedAfterRedaction = false;
|
|
18299
|
+
let rawCandidateCount = 0;
|
|
18300
|
+
let validCandidateCount = 0;
|
|
18225
18301
|
const callerOnExhaustedEmpty = options.extract.onExhaustedEmpty;
|
|
18226
18302
|
const callerOnCandidatesDropped = options.extract.onCandidatesDropped;
|
|
18303
|
+
const callerOnCandidatesParsed = options.extract.onCandidatesParsed;
|
|
18304
|
+
const tExtract = Date.now();
|
|
18227
18305
|
const candidates = await extractFacts(messages, {
|
|
18228
18306
|
...options.extract,
|
|
18229
18307
|
onExhaustedEmpty: (failure) => {
|
|
@@ -18234,8 +18312,14 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18234
18312
|
onCandidatesDropped: () => {
|
|
18235
18313
|
droppedAfterRedaction = true;
|
|
18236
18314
|
callerOnCandidatesDropped?.();
|
|
18315
|
+
},
|
|
18316
|
+
onCandidatesParsed: (stats) => {
|
|
18317
|
+
rawCandidateCount = stats.rawCount;
|
|
18318
|
+
validCandidateCount = stats.validCount;
|
|
18319
|
+
callerOnCandidatesParsed?.(stats);
|
|
18237
18320
|
}
|
|
18238
18321
|
});
|
|
18322
|
+
const extractMs = Date.now() - tExtract;
|
|
18239
18323
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
18240
18324
|
const log = getLogger();
|
|
18241
18325
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -18283,6 +18367,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18283
18367
|
const results = [];
|
|
18284
18368
|
const quarantinedInfo = [];
|
|
18285
18369
|
let failedWrites = 0;
|
|
18370
|
+
const tRetain = Date.now();
|
|
18286
18371
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
18287
18372
|
try {
|
|
18288
18373
|
const result = await retain(candidate.content, retainCtx, {
|
|
@@ -18349,6 +18434,21 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18349
18434
|
failedCount: failedWrites,
|
|
18350
18435
|
outcome,
|
|
18351
18436
|
quarantined: quarantinedInfo,
|
|
18437
|
+
funnel: {
|
|
18438
|
+
rawCandidateCount,
|
|
18439
|
+
validCandidateCount,
|
|
18440
|
+
afterRedactionCount: candidates.length,
|
|
18441
|
+
aboveConfidenceCount: filtered.length,
|
|
18442
|
+
// The PERSISTED quarantines (`quarantinedInfo`), not the screened list: a
|
|
18443
|
+
// screened candidate whose retain() throws is counted in `failedCount`,
|
|
18444
|
+
// and counting it here too would double it and break the identity below.
|
|
18445
|
+
// This also keeps the count equal to `quarantined.length` on the result.
|
|
18446
|
+
quarantinedCount: quarantinedInfo.length,
|
|
18447
|
+
retainedCount: results.length,
|
|
18448
|
+
failedCount: failedWrites
|
|
18449
|
+
},
|
|
18450
|
+
timings: { extractMs, retainMs: Date.now() - tRetain },
|
|
18451
|
+
model: options.extract.model ?? DEFAULT_EXTRACTION_MODEL,
|
|
18352
18452
|
// Only meaningful alongside `outcome: "empty-after-retry"`. Returned as well
|
|
18353
18453
|
// as pushed through the callback so a consumer that only inspects the result
|
|
18354
18454
|
// (rather than wiring a hook) can still report WHY.
|
|
@@ -18604,27 +18704,23 @@ function createAutoExtractor(options) {
|
|
|
18604
18704
|
const t0 = Date.now();
|
|
18605
18705
|
void (async () => {
|
|
18606
18706
|
try {
|
|
18607
|
-
const { candidates, results, failedCount, outcome, failure } = await extractAndRetain(
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
{
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
},
|
|
18623
|
-
...options.onMemoryQuarantined && {
|
|
18624
|
-
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
18625
|
-
}
|
|
18707
|
+
const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
18708
|
+
extract,
|
|
18709
|
+
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
18710
|
+
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
18711
|
+
...options.scope !== void 0 && { scope: options.scope },
|
|
18712
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
18713
|
+
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
18714
|
+
...injectionClassifierOptions !== void 0 && {
|
|
18715
|
+
injectionClassifier: injectionClassifierOptions
|
|
18716
|
+
},
|
|
18717
|
+
...options.onCandidateFailed && {
|
|
18718
|
+
onCandidateFailed: (candidate, error) => options.onCandidateFailed?.({ candidate, error, conversationId })
|
|
18719
|
+
},
|
|
18720
|
+
...options.onMemoryQuarantined && {
|
|
18721
|
+
onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
|
|
18626
18722
|
}
|
|
18627
|
-
);
|
|
18723
|
+
});
|
|
18628
18724
|
if (outcome !== "empty-after-retry") {
|
|
18629
18725
|
const advancedTo = window2[window2.length - 1].id;
|
|
18630
18726
|
stateFor(conversationId).watermark = advancedTo;
|
|
@@ -18645,6 +18741,9 @@ function createAutoExtractor(options) {
|
|
|
18645
18741
|
durationMs: Date.now() - t0,
|
|
18646
18742
|
conversationId,
|
|
18647
18743
|
outcome,
|
|
18744
|
+
funnel,
|
|
18745
|
+
timings,
|
|
18746
|
+
model,
|
|
18648
18747
|
// Only set alongside `outcome: "empty-after-retry"`. Spread so the key
|
|
18649
18748
|
// is absent rather than explicitly undefined on a healthy turn —
|
|
18650
18749
|
// analytics backends store an explicit undefined as a real value.
|