@anuma/sdk 6.18.0 → 6.19.1

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.
Files changed (30) hide show
  1. package/dist/expo/{chunk-JXN7LD6B.mjs → chunk-GRU24OP4.mjs} +13 -9
  2. package/dist/expo/{chunk-4Z2X4UYQ.mjs → chunk-WUG6GTHO.mjs} +10 -1
  3. package/dist/expo/{chunk-A2G6TRUK.mjs → chunk-XDBX4FZY.mjs} +1 -1
  4. package/dist/{react/consolidate-7NMKF7UC.mjs → expo/consolidate-XBYKAFKT.mjs} +2 -2
  5. package/dist/expo/index.cjs +24 -10
  6. package/dist/expo/index.d.mts +30 -3
  7. package/dist/expo/index.d.ts +30 -3
  8. package/dist/expo/index.mjs +6 -5
  9. package/dist/expo/{recall-TGRI5MN4.mjs → recall-PI7FZQNO.mjs} +2 -2
  10. package/dist/index.d.mts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/react/{chunk-TVPCH7ZZ.mjs → chunk-2EEPAOHJ.mjs} +13 -9
  13. package/dist/react/{chunk-7X7BNMGS.mjs → chunk-AVYB5IXC.mjs} +1 -1
  14. package/dist/react/{chunk-4Z2X4UYQ.mjs → chunk-WUG6GTHO.mjs} +10 -1
  15. package/dist/{expo/consolidate-ZM5JNULQ.mjs → react/consolidate-URHGJT7I.mjs} +2 -2
  16. package/dist/react/index.cjs +24 -10
  17. package/dist/react/index.d.mts +30 -3
  18. package/dist/react/index.d.ts +30 -3
  19. package/dist/react/index.mjs +6 -5
  20. package/dist/react/{recall-OKNLU335.mjs → recall-D6ODL36R.mjs} +2 -2
  21. package/dist/server/{chunk-4LPSEROP.mjs → chunk-RKQ4MRS2.mjs} +1 -1
  22. package/dist/server/{chunk-K7H7ICPK.mjs → chunk-SPHKT76E.mjs} +13 -9
  23. package/dist/server/{chunk-BSCEZOIW.mjs → chunk-YXL5VKCO.mjs} +10 -1
  24. package/dist/server/{consolidate-MSAXASHL.mjs → consolidate-54P6QZKU.mjs} +2 -2
  25. package/dist/server/index.cjs +24 -10
  26. package/dist/server/index.d.mts +30 -3
  27. package/dist/server/index.d.ts +30 -3
  28. package/dist/server/index.mjs +6 -5
  29. package/dist/server/{recall-YXJATOSD.mjs → recall-NLCZUGXN.mjs} +2 -2
  30. package/package.json +1 -1
@@ -6545,7 +6545,16 @@ async function callPortalJsonCompletion(req) {
6545
6545
  ...reinforce && { reinforceJsonContract: true }
6546
6546
  } : reinforce ? { ...req, reinforceJsonContract: true } : req;
6547
6547
  const outcome = await attemptPortalJson(attemptReq, endpoint);
6548
- if (outcome.kind === "ok") return outcome.value;
6548
+ if (outcome.kind === "ok") {
6549
+ req.onAttempt?.({ attempt, ok: true });
6550
+ return outcome.value;
6551
+ }
6552
+ req.onAttempt?.({
6553
+ attempt,
6554
+ ok: false,
6555
+ reason: outcome.code,
6556
+ ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus }
6557
+ });
6549
6558
  lastFailure = {
6550
6559
  reason: outcome.code,
6551
6560
  ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus },
@@ -8568,7 +8577,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
8568
8577
  let tailSlice = [];
8569
8578
  const itemById = new Map(items.map((i) => [i.id, i]));
8570
8579
  if (options?.rerank) {
8571
- const rerankTopN = options.rerankTopN ?? 30;
8580
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
8572
8581
  const ceWeight = options.ceWeight ?? 0.1;
8573
8582
  const headSlice = v2Ranked.slice(0, rerankTopN);
8574
8583
  const ceStart = nowMs2();
@@ -8614,9 +8623,12 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
8614
8623
  }
8615
8624
  if (sideLanesAsync.length > 0) {
8616
8625
  const headIds = combined.map((r) => r.uniqueId);
8617
- const fused = rrfFuse([headIds, headIds, ...sideLanesAsync], options?.rrfK);
8618
- const fusedHead = combined.map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
8619
- const seen = new Set(combined.map((r) => r.uniqueId));
8626
+ const tailIds = tailSlice.map((r) => r.uniqueId);
8627
+ const rankedIds = tailIds.length > 0 ? [...headIds, ...tailIds] : headIds;
8628
+ const fused = rrfFuse([rankedIds, rankedIds, ...sideLanesAsync], options?.rrfK);
8629
+ const fusedHead = [...combined, ...tailSlice].map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
8630
+ tailSlice = [];
8631
+ const seen = new Set(fusedHead.map((r) => r.uniqueId));
8620
8632
  const itemById2 = new Map(items.map((i) => [i.id, i]));
8621
8633
  for (const lane of sideLanesAsync) {
8622
8634
  for (const id of lane) {
@@ -8641,7 +8653,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
8641
8653
  const lambda = options.mmrLambda ?? 0.7;
8642
8654
  const mmrTopN = options.mmrTopN ?? 20;
8643
8655
  const itemById2 = new Map(items.map((i) => [i.id, i]));
8644
- const mmrCandidates = combined.slice(0, mmrTopN).map((r) => ({
8656
+ const mmrCandidates = [...combined, ...tailSlice].slice(0, mmrTopN).map((r) => ({
8645
8657
  id: r.uniqueId,
8646
8658
  score: r.similarity,
8647
8659
  embedding: itemById2.get(r.uniqueId)?.embedding ?? [],
@@ -8649,7 +8661,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
8649
8661
  }));
8650
8662
  const picked = applyMMR(mmrCandidates, limit, lambda);
8651
8663
  const pickedIds = new Set(picked.map((p) => p.id));
8652
- const resultMap = new Map(combined.map((r) => [r.uniqueId, r]));
8664
+ const resultMap = new Map([...combined, ...tailSlice].map((r) => [r.uniqueId, r]));
8653
8665
  const pickedResults = picked.map((p) => {
8654
8666
  const orig = resultMap.get(p.id);
8655
8667
  return {
@@ -8763,7 +8775,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
8763
8775
  }
8764
8776
  }
8765
8777
  if (options?.rerank && combined.length > 0) {
8766
- const rerankTopN = options.rerankTopN ?? 30;
8778
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
8767
8779
  const ceWeight = options.ceWeight ?? 0.1;
8768
8780
  const headSlice = combined.slice(0, rerankTopN);
8769
8781
  const tailSlice = combined.slice(rerankTopN);
@@ -9648,7 +9660,7 @@ ${formatted}`;
9648
9660
  }
9649
9661
  };
9650
9662
  }
9651
- var nowMs2, warnedProgrammaticDecomposeIgnored, SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
9663
+ var DEFAULT_RERANK_TOP_N, nowMs2, warnedProgrammaticDecomposeIgnored, SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
9652
9664
  var init_searchTool = __esm({
9653
9665
  "src/lib/memoryVault/searchTool.ts"() {
9654
9666
  "use strict";
@@ -9666,6 +9678,7 @@ var init_searchTool = __esm({
9666
9678
  init_bm25();
9667
9679
  init_decomposeQuery();
9668
9680
  init_lruCache();
9681
+ DEFAULT_RERANK_TOP_N = 5;
9669
9682
  nowMs2 = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
9670
9683
  warnedProgrammaticDecomposeIgnored = false;
9671
9684
  SUPERSESSION_SIMILARITY_THRESHOLD = 0.7;
@@ -18159,7 +18172,8 @@ Extract durable user facts.`,
18159
18172
  ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
18160
18173
  ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
18161
18174
  ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
18162
- ...options.backoffMs && { backoffMs: options.backoffMs }
18175
+ ...options.backoffMs && { backoffMs: options.backoffMs },
18176
+ ...options.onAttempt && { onAttempt: options.onAttempt }
18163
18177
  });
18164
18178
  if (parsed === null) {
18165
18179
  options.onExhaustedEmpty?.(failure ?? { reason: "empty-content", attempts: 1 });
@@ -6271,7 +6271,7 @@ declare function getEntitiesByMemoryIdsOp(ctx: EntityOperationsContext, memoryId
6271
6271
  *
6272
6272
  * @public
6273
6273
  */
6274
- type TaskType = "title" | "commit_message" | "memory_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
6274
+ type TaskType = "title" | "commit_message" | "memory_extract" | "memory_import_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
6275
6275
 
6276
6276
  /**
6277
6277
  * Shared portal LLM call for the memory pipeline.
@@ -6368,6 +6368,26 @@ type PortalLlmFailureReason =
6368
6368
  | "null-completion"
6369
6369
  /** `totalTimeoutMs` was spent before the next attempt could run. */
6370
6370
  | "time-budget-exhausted";
6371
+ /**
6372
+ * One attempt of a {@link callPortalJsonCompletion} call, reported to
6373
+ * `onAttempt` as it settles — success included. The wire-level diagnostic the
6374
+ * give-up hook cannot provide: a call that succeeds on its third try returns a
6375
+ * value and fires no `onFailure`, yet it cost three completions and its first
6376
+ * two answers were unusable. Extraction quality regressions have hidden in
6377
+ * exactly that shape (a prompt change that made the model answer `NONE` first,
6378
+ * JSON on retry), so the extraction eval gates on the first-attempt clean rate.
6379
+ *
6380
+ * @public
6381
+ */
6382
+ interface PortalLlmAttempt {
6383
+ /** 1-based attempt index. */
6384
+ attempt: number;
6385
+ /** Whether this attempt produced a parseable JSON value. */
6386
+ ok: boolean;
6387
+ /** Classification when `ok` is false. */
6388
+ reason?: PortalLlmFailureReason;
6389
+ httpStatus?: number;
6390
+ }
6371
6391
  /**
6372
6392
  * A give-up report: the classified {@link PortalLlmFailureReason} plus the
6373
6393
  * little context worth carrying into telemetry. Both extra fields are bounded
@@ -6624,7 +6644,7 @@ interface MemoryVaultSearchOptions {
6624
6644
  * When true, switches to the async pipeline (rankFusedVaultMemoriesAsync).
6625
6645
  */
6626
6646
  rerank?: boolean;
6627
- /** Number of CE rerank candidates. Default 30. */
6647
+ /** Number of CE rerank candidates. Default 5 ({@link DEFAULT_RERANK_TOP_N}). */
6628
6648
  rerankTopN?: number;
6629
6649
  /** Multiplicative cross-encoder blend weight. Default 0.1. Only used when `rerank` is true. */
6630
6650
  ceWeight?: number;
@@ -6979,7 +6999,8 @@ interface RecallOptions {
6979
6999
  * swallowed (diagnostics must never break retrieval). Off unless provided.
6980
7000
  */
6981
7001
  onDiagnostics?: (diagnostics: RecallDiagnostics) => void;
6982
- /** Number of candidates fed to the cross-encoder rerank stage. Default: 30. */
7002
+ /** Number of candidates fed to the cross-encoder rerank stage. Default: 5;
7003
+ * was 30 until 2026-08-13 — see anuma-ai/sdk#845. */
6983
7004
  rerankTopN?: number;
6984
7005
  /** Multiplicative cross-encoder blend weight. Default: 0.1. */
6985
7006
  ceWeight?: number;
@@ -7547,6 +7568,12 @@ interface ExtractFactsOptions extends PortalLlmAuth {
7547
7568
  * (i.e. redaction silently eating facts) is alarmable.
7548
7569
  */
7549
7570
  onCandidatesDropped?: () => void;
7571
+ /**
7572
+ * Per-attempt wire diagnostic, forwarded to {@link callPortalJsonCompletion}.
7573
+ * The extraction eval gates on it (first-attempt clean rate); production
7574
+ * callers may leave it unset.
7575
+ */
7576
+ onAttempt?: (attempt: PortalLlmAttempt) => void;
7550
7577
  }
7551
7578
  /**
7552
7579
  * Stage 1 — call the LLM to extract candidate facts from the recent
@@ -6271,7 +6271,7 @@ declare function getEntitiesByMemoryIdsOp(ctx: EntityOperationsContext, memoryId
6271
6271
  *
6272
6272
  * @public
6273
6273
  */
6274
- type TaskType = "title" | "commit_message" | "memory_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
6274
+ type TaskType = "title" | "commit_message" | "memory_extract" | "memory_import_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
6275
6275
 
6276
6276
  /**
6277
6277
  * Shared portal LLM call for the memory pipeline.
@@ -6368,6 +6368,26 @@ type PortalLlmFailureReason =
6368
6368
  | "null-completion"
6369
6369
  /** `totalTimeoutMs` was spent before the next attempt could run. */
6370
6370
  | "time-budget-exhausted";
6371
+ /**
6372
+ * One attempt of a {@link callPortalJsonCompletion} call, reported to
6373
+ * `onAttempt` as it settles — success included. The wire-level diagnostic the
6374
+ * give-up hook cannot provide: a call that succeeds on its third try returns a
6375
+ * value and fires no `onFailure`, yet it cost three completions and its first
6376
+ * two answers were unusable. Extraction quality regressions have hidden in
6377
+ * exactly that shape (a prompt change that made the model answer `NONE` first,
6378
+ * JSON on retry), so the extraction eval gates on the first-attempt clean rate.
6379
+ *
6380
+ * @public
6381
+ */
6382
+ interface PortalLlmAttempt {
6383
+ /** 1-based attempt index. */
6384
+ attempt: number;
6385
+ /** Whether this attempt produced a parseable JSON value. */
6386
+ ok: boolean;
6387
+ /** Classification when `ok` is false. */
6388
+ reason?: PortalLlmFailureReason;
6389
+ httpStatus?: number;
6390
+ }
6371
6391
  /**
6372
6392
  * A give-up report: the classified {@link PortalLlmFailureReason} plus the
6373
6393
  * little context worth carrying into telemetry. Both extra fields are bounded
@@ -6624,7 +6644,7 @@ interface MemoryVaultSearchOptions {
6624
6644
  * When true, switches to the async pipeline (rankFusedVaultMemoriesAsync).
6625
6645
  */
6626
6646
  rerank?: boolean;
6627
- /** Number of CE rerank candidates. Default 30. */
6647
+ /** Number of CE rerank candidates. Default 5 ({@link DEFAULT_RERANK_TOP_N}). */
6628
6648
  rerankTopN?: number;
6629
6649
  /** Multiplicative cross-encoder blend weight. Default 0.1. Only used when `rerank` is true. */
6630
6650
  ceWeight?: number;
@@ -6979,7 +6999,8 @@ interface RecallOptions {
6979
6999
  * swallowed (diagnostics must never break retrieval). Off unless provided.
6980
7000
  */
6981
7001
  onDiagnostics?: (diagnostics: RecallDiagnostics) => void;
6982
- /** Number of candidates fed to the cross-encoder rerank stage. Default: 30. */
7002
+ /** Number of candidates fed to the cross-encoder rerank stage. Default: 5;
7003
+ * was 30 until 2026-08-13 — see anuma-ai/sdk#845. */
6983
7004
  rerankTopN?: number;
6984
7005
  /** Multiplicative cross-encoder blend weight. Default: 0.1. */
6985
7006
  ceWeight?: number;
@@ -7547,6 +7568,12 @@ interface ExtractFactsOptions extends PortalLlmAuth {
7547
7568
  * (i.e. redaction silently eating facts) is alarmable.
7548
7569
  */
7549
7570
  onCandidatesDropped?: () => void;
7571
+ /**
7572
+ * Per-attempt wire diagnostic, forwarded to {@link callPortalJsonCompletion}.
7573
+ * The extraction eval gates on it (first-attempt clean rate); production
7574
+ * callers may leave it unset.
7575
+ */
7576
+ onAttempt?: (attempt: PortalLlmAttempt) => void;
7550
7577
  }
7551
7578
  /**
7552
7579
  * Stage 1 — call the LLM to extract candidate facts from the recent
@@ -179,14 +179,14 @@ import {
179
179
  updateVaultMemoryOp,
180
180
  useEncryption,
181
181
  vaultMemoryToStored
182
- } from "./chunk-TVPCH7ZZ.mjs";
182
+ } from "./chunk-2EEPAOHJ.mjs";
183
183
  import {
184
184
  PiiRedactor,
185
185
  createStreamingDeAnonymizer,
186
186
  isPiiRedactor,
187
187
  notifyConsolidationFallback,
188
188
  resolvePiiRedactor
189
- } from "./chunk-7X7BNMGS.mjs";
189
+ } from "./chunk-AVYB5IXC.mjs";
190
190
  import {
191
191
  INTERNAL_FLOW_MARKER,
192
192
  callPortalJsonCompletion,
@@ -202,7 +202,7 @@ import {
202
202
  taskTypeHeader,
203
203
  validateEndpointOverride,
204
204
  withInternalFlowMarker
205
- } from "./chunk-4Z2X4UYQ.mjs";
205
+ } from "./chunk-WUG6GTHO.mjs";
206
206
  import {
207
207
  BASE_URL,
208
208
  MCP_R2_DOMAIN,
@@ -7711,7 +7711,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
7711
7711
  content: m.content,
7712
7712
  similarity: m.similarity
7713
7713
  }));
7714
- const { consolidateMemory: doConsolidate } = await import("./consolidate-7NMKF7UC.mjs");
7714
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-URHGJT7I.mjs");
7715
7715
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
7716
7716
  if (decision.action === "create") return null;
7717
7717
  if (decision.action === "supersede" && decision.content) {
@@ -7953,7 +7953,8 @@ Extract durable user facts.`,
7953
7953
  ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
7954
7954
  ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
7955
7955
  ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
7956
- ...options.backoffMs && { backoffMs: options.backoffMs }
7956
+ ...options.backoffMs && { backoffMs: options.backoffMs },
7957
+ ...options.onAttempt && { onAttempt: options.onAttempt }
7957
7958
  });
7958
7959
  if (parsed === null) {
7959
7960
  options.onExhaustedEmpty?.(failure ?? { reason: "empty-content", attempts: 1 });
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-TVPCH7ZZ.mjs";
4
- import "./chunk-4Z2X4UYQ.mjs";
3
+ } from "./chunk-2EEPAOHJ.mjs";
4
+ import "./chunk-WUG6GTHO.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
7
7
  recall
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getLogger
3
- } from "./chunk-BSCEZOIW.mjs";
3
+ } from "./chunk-YXL5VKCO.mjs";
4
4
 
5
5
  // src/lib/pii/patterns.ts
6
6
  function luhnCheck(digits) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  callPortalJsonCompletion,
3
3
  getLogger
4
- } from "./chunk-BSCEZOIW.mjs";
4
+ } from "./chunk-YXL5VKCO.mjs";
5
5
  import {
6
6
  BASE_URL,
7
7
  __commonJS,
@@ -19658,6 +19658,7 @@ function createVaultEmbeddingCache(maxSize = DEFAULT_VAULT_CACHE_SIZE) {
19658
19658
  }
19659
19659
 
19660
19660
  // src/lib/memoryVault/searchTool.ts
19661
+ var DEFAULT_RERANK_TOP_N = 5;
19661
19662
  var nowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
19662
19663
  var warnedProgrammaticDecomposeIgnored = false;
19663
19664
  function normalizeEventTimeKind(kind) {
@@ -19888,7 +19889,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
19888
19889
  let tailSlice = [];
19889
19890
  const itemById = new Map(items.map((i) => [i.id, i]));
19890
19891
  if (options?.rerank) {
19891
- const rerankTopN = options.rerankTopN ?? 30;
19892
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
19892
19893
  const ceWeight = options.ceWeight ?? 0.1;
19893
19894
  const headSlice = v2Ranked.slice(0, rerankTopN);
19894
19895
  const ceStart = nowMs();
@@ -19934,9 +19935,12 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
19934
19935
  }
19935
19936
  if (sideLanesAsync.length > 0) {
19936
19937
  const headIds = combined.map((r) => r.uniqueId);
19937
- const fused = rrfFuse([headIds, headIds, ...sideLanesAsync], options?.rrfK);
19938
- const fusedHead = combined.map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
19939
- const seen = new Set(combined.map((r) => r.uniqueId));
19938
+ const tailIds = tailSlice.map((r) => r.uniqueId);
19939
+ const rankedIds = tailIds.length > 0 ? [...headIds, ...tailIds] : headIds;
19940
+ const fused = rrfFuse([rankedIds, rankedIds, ...sideLanesAsync], options?.rrfK);
19941
+ const fusedHead = [...combined, ...tailSlice].map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
19942
+ tailSlice = [];
19943
+ const seen = new Set(fusedHead.map((r) => r.uniqueId));
19940
19944
  const itemById2 = new Map(items.map((i) => [i.id, i]));
19941
19945
  for (const lane of sideLanesAsync) {
19942
19946
  for (const id of lane) {
@@ -19961,7 +19965,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
19961
19965
  const lambda = options.mmrLambda ?? 0.7;
19962
19966
  const mmrTopN = options.mmrTopN ?? 20;
19963
19967
  const itemById2 = new Map(items.map((i) => [i.id, i]));
19964
- const mmrCandidates = combined.slice(0, mmrTopN).map((r) => ({
19968
+ const mmrCandidates = [...combined, ...tailSlice].slice(0, mmrTopN).map((r) => ({
19965
19969
  id: r.uniqueId,
19966
19970
  score: r.similarity,
19967
19971
  embedding: itemById2.get(r.uniqueId)?.embedding ?? [],
@@ -19969,7 +19973,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
19969
19973
  }));
19970
19974
  const picked = applyMMR(mmrCandidates, limit, lambda);
19971
19975
  const pickedIds = new Set(picked.map((p) => p.id));
19972
- const resultMap = new Map(combined.map((r) => [r.uniqueId, r]));
19976
+ const resultMap = new Map([...combined, ...tailSlice].map((r) => [r.uniqueId, r]));
19973
19977
  const pickedResults = picked.map((p) => {
19974
19978
  const orig = resultMap.get(p.id);
19975
19979
  return {
@@ -20083,7 +20087,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
20083
20087
  }
20084
20088
  }
20085
20089
  if (options?.rerank && combined.length > 0) {
20086
- const rerankTopN = options.rerankTopN ?? 30;
20090
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
20087
20091
  const ceWeight = options.ceWeight ?? 0.1;
20088
20092
  const headSlice = combined.slice(0, rerankTopN);
20089
20093
  const tailSlice = combined.slice(rerankTopN);
@@ -20923,7 +20927,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
20923
20927
  subQueries = decomp.subQueries;
20924
20928
  }
20925
20929
  }
20926
- const { recall: recall2 } = await import("./recall-YXJATOSD.mjs");
20930
+ const { recall: recall2 } = await import("./recall-NLCZUGXN.mjs");
20927
20931
  let recallDegraded = [];
20928
20932
  const result = await recall2(
20929
20933
  query,
@@ -159,7 +159,16 @@ async function callPortalJsonCompletion(req) {
159
159
  ...reinforce && { reinforceJsonContract: true }
160
160
  } : reinforce ? { ...req, reinforceJsonContract: true } : req;
161
161
  const outcome = await attemptPortalJson(attemptReq, endpoint);
162
- if (outcome.kind === "ok") return outcome.value;
162
+ if (outcome.kind === "ok") {
163
+ req.onAttempt?.({ attempt, ok: true });
164
+ return outcome.value;
165
+ }
166
+ req.onAttempt?.({
167
+ attempt,
168
+ ok: false,
169
+ reason: outcome.code,
170
+ ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus }
171
+ });
163
172
  lastFailure = {
164
173
  reason: outcome.code,
165
174
  ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus },
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  notifyConsolidationFallback,
3
3
  resolvePiiRedactor
4
- } from "./chunk-4LPSEROP.mjs";
4
+ } from "./chunk-RKQ4MRS2.mjs";
5
5
  import {
6
6
  callPortalJsonCompletion
7
- } from "./chunk-BSCEZOIW.mjs";
7
+ } from "./chunk-YXL5VKCO.mjs";
8
8
  import "./chunk-3RPGXXPZ.mjs";
9
9
 
10
10
  // src/lib/memory/consolidate.ts
@@ -20704,7 +20704,16 @@ async function callPortalJsonCompletion(req) {
20704
20704
  ...reinforce && { reinforceJsonContract: true }
20705
20705
  } : reinforce ? { ...req, reinforceJsonContract: true } : req;
20706
20706
  const outcome = await attemptPortalJson(attemptReq, endpoint);
20707
- if (outcome.kind === "ok") return outcome.value;
20707
+ if (outcome.kind === "ok") {
20708
+ req.onAttempt?.({ attempt, ok: true });
20709
+ return outcome.value;
20710
+ }
20711
+ req.onAttempt?.({
20712
+ attempt,
20713
+ ok: false,
20714
+ reason: outcome.code,
20715
+ ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus }
20716
+ });
20708
20717
  lastFailure = {
20709
20718
  reason: outcome.code,
20710
20719
  ...outcome.httpStatus !== void 0 && { httpStatus: outcome.httpStatus },
@@ -22274,7 +22283,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
22274
22283
  let tailSlice = [];
22275
22284
  const itemById = new Map(items.map((i) => [i.id, i]));
22276
22285
  if (options?.rerank) {
22277
- const rerankTopN = options.rerankTopN ?? 30;
22286
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
22278
22287
  const ceWeight = options.ceWeight ?? 0.1;
22279
22288
  const headSlice = v2Ranked.slice(0, rerankTopN);
22280
22289
  const ceStart = nowMs2();
@@ -22320,9 +22329,12 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
22320
22329
  }
22321
22330
  if (sideLanesAsync.length > 0) {
22322
22331
  const headIds = combined.map((r) => r.uniqueId);
22323
- const fused = rrfFuse([headIds, headIds, ...sideLanesAsync], options?.rrfK);
22324
- const fusedHead = combined.map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
22325
- const seen = new Set(combined.map((r) => r.uniqueId));
22332
+ const tailIds = tailSlice.map((r) => r.uniqueId);
22333
+ const rankedIds = tailIds.length > 0 ? [...headIds, ...tailIds] : headIds;
22334
+ const fused = rrfFuse([rankedIds, rankedIds, ...sideLanesAsync], options?.rrfK);
22335
+ const fusedHead = [...combined, ...tailSlice].map((r) => ({ ...r, similarity: fused.get(r.uniqueId) ?? r.similarity })).sort((a, b) => b.similarity - a.similarity);
22336
+ tailSlice = [];
22337
+ const seen = new Set(fusedHead.map((r) => r.uniqueId));
22326
22338
  const itemById2 = new Map(items.map((i) => [i.id, i]));
22327
22339
  for (const lane of sideLanesAsync) {
22328
22340
  for (const id of lane) {
@@ -22347,7 +22359,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
22347
22359
  const lambda = options.mmrLambda ?? 0.7;
22348
22360
  const mmrTopN = options.mmrTopN ?? 20;
22349
22361
  const itemById2 = new Map(items.map((i) => [i.id, i]));
22350
- const mmrCandidates = combined.slice(0, mmrTopN).map((r) => ({
22362
+ const mmrCandidates = [...combined, ...tailSlice].slice(0, mmrTopN).map((r) => ({
22351
22363
  id: r.uniqueId,
22352
22364
  score: r.similarity,
22353
22365
  embedding: itemById2.get(r.uniqueId)?.embedding ?? [],
@@ -22355,7 +22367,7 @@ async function rankFusedVaultMemoriesAsync(query, queryEmbedding, items, options
22355
22367
  }));
22356
22368
  const picked = applyMMR(mmrCandidates, limit, lambda);
22357
22369
  const pickedIds = new Set(picked.map((p) => p.id));
22358
- const resultMap = new Map(combined.map((r) => [r.uniqueId, r]));
22370
+ const resultMap = new Map([...combined, ...tailSlice].map((r) => [r.uniqueId, r]));
22359
22371
  const pickedResults = picked.map((p) => {
22360
22372
  const orig = resultMap.get(p.id);
22361
22373
  return {
@@ -22469,7 +22481,7 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
22469
22481
  }
22470
22482
  }
22471
22483
  if (options?.rerank && combined.length > 0) {
22472
- const rerankTopN = options.rerankTopN ?? 30;
22484
+ const rerankTopN = options.rerankTopN ?? DEFAULT_RERANK_TOP_N;
22473
22485
  const ceWeight = options.ceWeight ?? 0.1;
22474
22486
  const headSlice = combined.slice(0, rerankTopN);
22475
22487
  const tailSlice = combined.slice(rerankTopN);
@@ -23354,7 +23366,7 @@ ${formatted}`;
23354
23366
  }
23355
23367
  };
23356
23368
  }
23357
- var nowMs2, warnedProgrammaticDecomposeIgnored, SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
23369
+ var DEFAULT_RERANK_TOP_N, nowMs2, warnedProgrammaticDecomposeIgnored, SUPERSESSION_SIMILARITY_THRESHOLD, SUPERSESSION_MIN_AGE_GAP_MS, SUPERSESSION_BOOST_FACTOR, SUPERSESSION_MAX_WINDOW, EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL;
23358
23370
  var init_searchTool = __esm({
23359
23371
  "src/lib/memoryVault/searchTool.ts"() {
23360
23372
  "use strict";
@@ -23372,6 +23384,7 @@ var init_searchTool = __esm({
23372
23384
  init_bm25();
23373
23385
  init_decomposeQuery();
23374
23386
  init_lruCache();
23387
+ DEFAULT_RERANK_TOP_N = 5;
23375
23388
  nowMs2 = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
23376
23389
  warnedProgrammaticDecomposeIgnored = false;
23377
23390
  SUPERSESSION_SIMILARITY_THRESHOLD = 0.7;
@@ -29772,7 +29785,8 @@ Extract durable user facts.`,
29772
29785
  ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
29773
29786
  ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
29774
29787
  ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
29775
- ...options.backoffMs && { backoffMs: options.backoffMs }
29788
+ ...options.backoffMs && { backoffMs: options.backoffMs },
29789
+ ...options.onAttempt && { onAttempt: options.onAttempt }
29776
29790
  });
29777
29791
  if (parsed === null) {
29778
29792
  options.onExhaustedEmpty?.(failure ?? { reason: "empty-content", attempts: 1 });
@@ -4766,7 +4766,7 @@ interface EntityOperationsContext {
4766
4766
  *
4767
4767
  * @public
4768
4768
  */
4769
- type TaskType = "title" | "commit_message" | "memory_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
4769
+ type TaskType = "title" | "commit_message" | "memory_extract" | "memory_import_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
4770
4770
 
4771
4771
  /**
4772
4772
  * Shared portal LLM call for the memory pipeline.
@@ -4863,6 +4863,26 @@ type PortalLlmFailureReason =
4863
4863
  | "null-completion"
4864
4864
  /** `totalTimeoutMs` was spent before the next attempt could run. */
4865
4865
  | "time-budget-exhausted";
4866
+ /**
4867
+ * One attempt of a {@link callPortalJsonCompletion} call, reported to
4868
+ * `onAttempt` as it settles — success included. The wire-level diagnostic the
4869
+ * give-up hook cannot provide: a call that succeeds on its third try returns a
4870
+ * value and fires no `onFailure`, yet it cost three completions and its first
4871
+ * two answers were unusable. Extraction quality regressions have hidden in
4872
+ * exactly that shape (a prompt change that made the model answer `NONE` first,
4873
+ * JSON on retry), so the extraction eval gates on the first-attempt clean rate.
4874
+ *
4875
+ * @public
4876
+ */
4877
+ interface PortalLlmAttempt {
4878
+ /** 1-based attempt index. */
4879
+ attempt: number;
4880
+ /** Whether this attempt produced a parseable JSON value. */
4881
+ ok: boolean;
4882
+ /** Classification when `ok` is false. */
4883
+ reason?: PortalLlmFailureReason;
4884
+ httpStatus?: number;
4885
+ }
4866
4886
  /**
4867
4887
  * A give-up report: the classified {@link PortalLlmFailureReason} plus the
4868
4888
  * little context worth carrying into telemetry. Both extra fields are bounded
@@ -5210,7 +5230,7 @@ interface MemoryVaultSearchOptions {
5210
5230
  * When true, switches to the async pipeline (rankFusedVaultMemoriesAsync).
5211
5231
  */
5212
5232
  rerank?: boolean;
5213
- /** Number of CE rerank candidates. Default 30. */
5233
+ /** Number of CE rerank candidates. Default 5 ({@link DEFAULT_RERANK_TOP_N}). */
5214
5234
  rerankTopN?: number;
5215
5235
  /** Multiplicative cross-encoder blend weight. Default 0.1. Only used when `rerank` is true. */
5216
5236
  ceWeight?: number;
@@ -5565,7 +5585,8 @@ interface RecallOptions {
5565
5585
  * swallowed (diagnostics must never break retrieval). Off unless provided.
5566
5586
  */
5567
5587
  onDiagnostics?: (diagnostics: RecallDiagnostics) => void;
5568
- /** Number of candidates fed to the cross-encoder rerank stage. Default: 30. */
5588
+ /** Number of candidates fed to the cross-encoder rerank stage. Default: 5;
5589
+ * was 30 until 2026-08-13 — see anuma-ai/sdk#845. */
5569
5590
  rerankTopN?: number;
5570
5591
  /** Multiplicative cross-encoder blend weight. Default: 0.1. */
5571
5592
  ceWeight?: number;
@@ -6133,6 +6154,12 @@ interface ExtractFactsOptions extends PortalLlmAuth {
6133
6154
  * (i.e. redaction silently eating facts) is alarmable.
6134
6155
  */
6135
6156
  onCandidatesDropped?: () => void;
6157
+ /**
6158
+ * Per-attempt wire diagnostic, forwarded to {@link callPortalJsonCompletion}.
6159
+ * The extraction eval gates on it (first-attempt clean rate); production
6160
+ * callers may leave it unset.
6161
+ */
6162
+ onAttempt?: (attempt: PortalLlmAttempt) => void;
6136
6163
  }
6137
6164
  /**
6138
6165
  * Stage 1 — call the LLM to extract candidate facts from the recent
@@ -4766,7 +4766,7 @@ interface EntityOperationsContext {
4766
4766
  *
4767
4767
  * @public
4768
4768
  */
4769
- type TaskType = "title" | "commit_message" | "memory_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
4769
+ type TaskType = "title" | "commit_message" | "memory_extract" | "memory_import_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
4770
4770
 
4771
4771
  /**
4772
4772
  * Shared portal LLM call for the memory pipeline.
@@ -4863,6 +4863,26 @@ type PortalLlmFailureReason =
4863
4863
  | "null-completion"
4864
4864
  /** `totalTimeoutMs` was spent before the next attempt could run. */
4865
4865
  | "time-budget-exhausted";
4866
+ /**
4867
+ * One attempt of a {@link callPortalJsonCompletion} call, reported to
4868
+ * `onAttempt` as it settles — success included. The wire-level diagnostic the
4869
+ * give-up hook cannot provide: a call that succeeds on its third try returns a
4870
+ * value and fires no `onFailure`, yet it cost three completions and its first
4871
+ * two answers were unusable. Extraction quality regressions have hidden in
4872
+ * exactly that shape (a prompt change that made the model answer `NONE` first,
4873
+ * JSON on retry), so the extraction eval gates on the first-attempt clean rate.
4874
+ *
4875
+ * @public
4876
+ */
4877
+ interface PortalLlmAttempt {
4878
+ /** 1-based attempt index. */
4879
+ attempt: number;
4880
+ /** Whether this attempt produced a parseable JSON value. */
4881
+ ok: boolean;
4882
+ /** Classification when `ok` is false. */
4883
+ reason?: PortalLlmFailureReason;
4884
+ httpStatus?: number;
4885
+ }
4866
4886
  /**
4867
4887
  * A give-up report: the classified {@link PortalLlmFailureReason} plus the
4868
4888
  * little context worth carrying into telemetry. Both extra fields are bounded
@@ -5210,7 +5230,7 @@ interface MemoryVaultSearchOptions {
5210
5230
  * When true, switches to the async pipeline (rankFusedVaultMemoriesAsync).
5211
5231
  */
5212
5232
  rerank?: boolean;
5213
- /** Number of CE rerank candidates. Default 30. */
5233
+ /** Number of CE rerank candidates. Default 5 ({@link DEFAULT_RERANK_TOP_N}). */
5214
5234
  rerankTopN?: number;
5215
5235
  /** Multiplicative cross-encoder blend weight. Default 0.1. Only used when `rerank` is true. */
5216
5236
  ceWeight?: number;
@@ -5565,7 +5585,8 @@ interface RecallOptions {
5565
5585
  * swallowed (diagnostics must never break retrieval). Off unless provided.
5566
5586
  */
5567
5587
  onDiagnostics?: (diagnostics: RecallDiagnostics) => void;
5568
- /** Number of candidates fed to the cross-encoder rerank stage. Default: 30. */
5588
+ /** Number of candidates fed to the cross-encoder rerank stage. Default: 5;
5589
+ * was 30 until 2026-08-13 — see anuma-ai/sdk#845. */
5569
5590
  rerankTopN?: number;
5570
5591
  /** Multiplicative cross-encoder blend weight. Default: 0.1. */
5571
5592
  ceWeight?: number;
@@ -6133,6 +6154,12 @@ interface ExtractFactsOptions extends PortalLlmAuth {
6133
6154
  * (i.e. redaction silently eating facts) is alarmable.
6134
6155
  */
6135
6156
  onCandidatesDropped?: () => void;
6157
+ /**
6158
+ * Per-attempt wire diagnostic, forwarded to {@link callPortalJsonCompletion}.
6159
+ * The extraction eval gates on it (first-attempt clean rate); production
6160
+ * callers may leave it unset.
6161
+ */
6162
+ onAttempt?: (attempt: PortalLlmAttempt) => void;
6136
6163
  }
6137
6164
  /**
6138
6165
  * Stage 1 — call the LLM to extract candidate facts from the recent