@anuma/sdk 5.0.1 → 5.0.3

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.
@@ -55,12 +55,14 @@ async function consolidateMemory(newContent, candidates, options) {
55
55
  if (trimmed.length === 0) return fallback;
56
56
  if (candidates.length === 0) return fallback;
57
57
  const redactor = resolvePiiRedactor(options.piiRedaction);
58
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
59
- const candidateText = candidates.map((c, i) => {
60
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
61
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
62
- ${safeContent}`;
63
- }).join("\n");
58
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
59
+ const rows = [];
60
+ for (const [i, c] of candidates.entries()) {
61
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
62
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
63
+ ${safeContent}`);
64
+ }
65
+ const candidateText = rows.join("\n");
64
66
  const userMessage = `New memory:
65
67
  ${safeTrimmed}
66
68
 
@@ -8755,12 +8755,14 @@ async function consolidateMemory(newContent, candidates, options) {
8755
8755
  if (trimmed.length === 0) return fallback;
8756
8756
  if (candidates.length === 0) return fallback;
8757
8757
  const redactor = resolvePiiRedactor(options.piiRedaction);
8758
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
8759
- const candidateText = candidates.map((c, i) => {
8760
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
8761
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
8762
- ${safeContent}`;
8763
- }).join("\n");
8758
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
8759
+ const rows = [];
8760
+ for (const [i, c] of candidates.entries()) {
8761
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
8762
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
8763
+ ${safeContent}`);
8764
+ }
8765
+ const candidateText = rows.join("\n");
8764
8766
  const userMessage = `New memory:
8765
8767
  ${safeTrimmed}
8766
8768
 
@@ -15190,10 +15192,12 @@ async function classifyInjectionCandidates(candidates, options) {
15190
15192
  );
15191
15193
  }
15192
15194
  const redactor = resolvePiiRedactor(options.piiRedaction);
15193
- const numbered = scope.map((c, i) => {
15194
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
15195
- return `[${i + 1}] ${safe}`;
15196
- }).join("\n");
15195
+ const lines = [];
15196
+ for (const [i, c] of scope.entries()) {
15197
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
15198
+ lines.push(`[${i + 1}] ${safe}`);
15199
+ }
15200
+ const numbered = lines.join("\n");
15197
15201
  let parsed;
15198
15202
  try {
15199
15203
  parsed = await callPortalJsonCompletion({
@@ -16515,7 +16519,7 @@ function createLlmDecayClassifier(options) {
16515
16519
  }
16516
16520
  if (!content || content.trim().length === 0) return ruleVerdict;
16517
16521
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
16518
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
16522
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
16519
16523
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
16520
16524
  let parsed;
16521
16525
  try {
@@ -17277,7 +17281,14 @@ async function synthesizeProfile(ctx, options = {}) {
17277
17281
  observationTrends
17278
17282
  };
17279
17283
  }
17280
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
17284
+ const staleKeys = await computeStaleFacetKeys(
17285
+ ctx,
17286
+ memories,
17287
+ facets,
17288
+ previous,
17289
+ watermark,
17290
+ options.reviewedMemoryIds
17291
+ );
17281
17292
  const settled = await Promise.allSettled(
17282
17293
  facets.map(async (facet) => {
17283
17294
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -17338,7 +17349,7 @@ function computeVaultWatermark(memories) {
17338
17349
  }
17339
17350
  return max;
17340
17351
  }
17341
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
17352
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
17342
17353
  const allKeys = new Set(facets.map((f) => f.key));
17343
17354
  if (previous && watermark < previous.vaultWatermark) return allKeys;
17344
17355
  if (!previous) return allKeys;
@@ -17361,9 +17372,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
17361
17372
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
17362
17373
  }
17363
17374
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
17364
- const toAttribute = changed.filter(
17375
+ let toAttribute = changed.filter(
17365
17376
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
17366
17377
  );
17378
+ if (reviewedMemoryIds !== void 0) {
17379
+ const allowed = new Set(reviewedMemoryIds);
17380
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
17381
+ }
17367
17382
  if (toAttribute.length > 0) {
17368
17383
  const attributed = await attributeFacts(ctx, toAttribute, facets);
17369
17384
  if (attributed === null) return allKeys;
@@ -17645,17 +17660,22 @@ async function extractEntitiesForMemories(memories, options) {
17645
17660
  const out = /* @__PURE__ */ new Map();
17646
17661
  if (memories.length === 0) return out;
17647
17662
  const redactor = resolvePiiRedactor(options.piiRedaction);
17648
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
17663
+ const vocabulary = [];
17664
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
17665
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
17666
+ }
17649
17667
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
17650
17668
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
17651
17669
 
17652
17670
  ` : "";
17653
17671
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
17654
17672
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
17655
- const listing = batch.map((m) => {
17673
+ const rows = [];
17674
+ for (const m of batch) {
17656
17675
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
17657
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
17658
- }).join("\n");
17676
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
17677
+ }
17678
+ const listing = rows.join("\n");
17659
17679
  const parsed = await callPortalJsonCompletion({
17660
17680
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
17661
17681
  ...options.getToken !== void 0 && { getToken: options.getToken },
@@ -6193,10 +6193,12 @@ async function classifyInjectionCandidates(candidates, options) {
6193
6193
  );
6194
6194
  }
6195
6195
  const redactor = resolvePiiRedactor(options.piiRedaction);
6196
- const numbered = scope.map((c, i) => {
6197
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
6198
- return `[${i + 1}] ${safe}`;
6199
- }).join("\n");
6196
+ const lines = [];
6197
+ for (const [i, c] of scope.entries()) {
6198
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
6199
+ lines.push(`[${i + 1}] ${safe}`);
6200
+ }
6201
+ const numbered = lines.join("\n");
6200
6202
  let parsed;
6201
6203
  try {
6202
6204
  parsed = await callPortalJsonCompletion({
@@ -6677,7 +6679,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
6677
6679
  content: m.content,
6678
6680
  similarity: m.similarity
6679
6681
  }));
6680
- const { consolidateMemory: doConsolidate } = await import("./consolidate-KASO7JDS.mjs");
6682
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-T6GZ5YQ4.mjs");
6681
6683
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
6682
6684
  if (decision.action === "create") return null;
6683
6685
  if (decision.action === "supersede" && decision.content) {
@@ -7501,7 +7503,7 @@ function createLlmDecayClassifier(options) {
7501
7503
  }
7502
7504
  if (!content || content.trim().length === 0) return ruleVerdict;
7503
7505
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
7504
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
7506
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
7505
7507
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
7506
7508
  let parsed;
7507
7509
  try {
@@ -8235,7 +8237,14 @@ async function synthesizeProfile(ctx, options = {}) {
8235
8237
  observationTrends
8236
8238
  };
8237
8239
  }
8238
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
8240
+ const staleKeys = await computeStaleFacetKeys(
8241
+ ctx,
8242
+ memories,
8243
+ facets,
8244
+ previous,
8245
+ watermark,
8246
+ options.reviewedMemoryIds
8247
+ );
8239
8248
  const settled = await Promise.allSettled(
8240
8249
  facets.map(async (facet) => {
8241
8250
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -8296,7 +8305,7 @@ function computeVaultWatermark(memories) {
8296
8305
  }
8297
8306
  return max;
8298
8307
  }
8299
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
8308
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
8300
8309
  const allKeys = new Set(facets.map((f) => f.key));
8301
8310
  if (previous && watermark < previous.vaultWatermark) return allKeys;
8302
8311
  if (!previous) return allKeys;
@@ -8319,9 +8328,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
8319
8328
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
8320
8329
  }
8321
8330
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
8322
- const toAttribute = changed.filter(
8331
+ let toAttribute = changed.filter(
8323
8332
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
8324
8333
  );
8334
+ if (reviewedMemoryIds !== void 0) {
8335
+ const allowed = new Set(reviewedMemoryIds);
8336
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
8337
+ }
8325
8338
  if (toAttribute.length > 0) {
8326
8339
  const attributed = await attributeFacts(ctx, toAttribute, facets);
8327
8340
  if (attributed === null) return allKeys;
@@ -8598,17 +8611,22 @@ async function extractEntitiesForMemories(memories, options) {
8598
8611
  const out = /* @__PURE__ */ new Map();
8599
8612
  if (memories.length === 0) return out;
8600
8613
  const redactor = resolvePiiRedactor(options.piiRedaction);
8601
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
8614
+ const vocabulary = [];
8615
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
8616
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
8617
+ }
8602
8618
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
8603
8619
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
8604
8620
 
8605
8621
  ` : "";
8606
8622
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
8607
8623
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
8608
- const listing = batch.map((m) => {
8624
+ const rows = [];
8625
+ for (const m of batch) {
8609
8626
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
8610
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
8611
- }).join("\n");
8627
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
8628
+ }
8629
+ const listing = rows.join("\n");
8612
8630
  const parsed = await callPortalJsonCompletion({
8613
8631
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
8614
8632
  ...options.getToken !== void 0 && { getToken: options.getToken },
@@ -55,12 +55,14 @@ async function consolidateMemory(newContent, candidates, options) {
55
55
  if (trimmed.length === 0) return fallback;
56
56
  if (candidates.length === 0) return fallback;
57
57
  const redactor = resolvePiiRedactor(options.piiRedaction);
58
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
59
- const candidateText = candidates.map((c, i) => {
60
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
61
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
62
- ${safeContent}`;
63
- }).join("\n");
58
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
59
+ const rows = [];
60
+ for (const [i, c] of candidates.entries()) {
61
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
62
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
63
+ ${safeContent}`);
64
+ }
65
+ const candidateText = rows.join("\n");
64
66
  const userMessage = `New memory:
65
67
  ${safeTrimmed}
66
68
 
@@ -9038,12 +9038,14 @@ async function consolidateMemory(newContent, candidates, options) {
9038
9038
  if (trimmed.length === 0) return fallback;
9039
9039
  if (candidates.length === 0) return fallback;
9040
9040
  const redactor = resolvePiiRedactor(options.piiRedaction);
9041
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
9042
- const candidateText = candidates.map((c, i) => {
9043
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
9044
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
9045
- ${safeContent}`;
9046
- }).join("\n");
9041
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
9042
+ const rows = [];
9043
+ for (const [i, c] of candidates.entries()) {
9044
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
9045
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
9046
+ ${safeContent}`);
9047
+ }
9048
+ const candidateText = rows.join("\n");
9047
9049
  const userMessage = `New memory:
9048
9050
  ${safeTrimmed}
9049
9051
 
@@ -16489,10 +16491,12 @@ async function classifyInjectionCandidates(candidates, options) {
16489
16491
  );
16490
16492
  }
16491
16493
  const redactor = resolvePiiRedactor(options.piiRedaction);
16492
- const numbered = scope.map((c, i) => {
16493
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
16494
- return `[${i + 1}] ${safe}`;
16495
- }).join("\n");
16494
+ const lines = [];
16495
+ for (const [i, c] of scope.entries()) {
16496
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
16497
+ lines.push(`[${i + 1}] ${safe}`);
16498
+ }
16499
+ const numbered = lines.join("\n");
16496
16500
  let parsed;
16497
16501
  try {
16498
16502
  parsed = await callPortalJsonCompletion({
@@ -17814,7 +17818,7 @@ function createLlmDecayClassifier(options) {
17814
17818
  }
17815
17819
  if (!content || content.trim().length === 0) return ruleVerdict;
17816
17820
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
17817
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
17821
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
17818
17822
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
17819
17823
  let parsed;
17820
17824
  try {
@@ -18576,7 +18580,14 @@ async function synthesizeProfile(ctx, options = {}) {
18576
18580
  observationTrends
18577
18581
  };
18578
18582
  }
18579
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
18583
+ const staleKeys = await computeStaleFacetKeys(
18584
+ ctx,
18585
+ memories,
18586
+ facets,
18587
+ previous,
18588
+ watermark,
18589
+ options.reviewedMemoryIds
18590
+ );
18580
18591
  const settled = await Promise.allSettled(
18581
18592
  facets.map(async (facet) => {
18582
18593
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -18637,7 +18648,7 @@ function computeVaultWatermark(memories) {
18637
18648
  }
18638
18649
  return max;
18639
18650
  }
18640
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
18651
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
18641
18652
  const allKeys = new Set(facets.map((f) => f.key));
18642
18653
  if (previous && watermark < previous.vaultWatermark) return allKeys;
18643
18654
  if (!previous) return allKeys;
@@ -18660,9 +18671,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
18660
18671
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
18661
18672
  }
18662
18673
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
18663
- const toAttribute = changed.filter(
18674
+ let toAttribute = changed.filter(
18664
18675
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
18665
18676
  );
18677
+ if (reviewedMemoryIds !== void 0) {
18678
+ const allowed = new Set(reviewedMemoryIds);
18679
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
18680
+ }
18666
18681
  if (toAttribute.length > 0) {
18667
18682
  const attributed = await attributeFacts(ctx, toAttribute, facets);
18668
18683
  if (attributed === null) return allKeys;
@@ -18944,17 +18959,22 @@ async function extractEntitiesForMemories(memories, options) {
18944
18959
  const out = /* @__PURE__ */ new Map();
18945
18960
  if (memories.length === 0) return out;
18946
18961
  const redactor = resolvePiiRedactor(options.piiRedaction);
18947
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
18962
+ const vocabulary = [];
18963
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
18964
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
18965
+ }
18948
18966
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
18949
18967
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
18950
18968
 
18951
18969
  ` : "";
18952
18970
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
18953
18971
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
18954
- const listing = batch.map((m) => {
18972
+ const rows = [];
18973
+ for (const m of batch) {
18955
18974
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
18956
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
18957
- }).join("\n");
18975
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
18976
+ }
18977
+ const listing = rows.join("\n");
18958
18978
  const parsed = await callPortalJsonCompletion({
18959
18979
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
18960
18980
  ...options.getToken !== void 0 && { getToken: options.getToken },
@@ -7010,10 +7010,12 @@ async function classifyInjectionCandidates(candidates, options) {
7010
7010
  );
7011
7011
  }
7012
7012
  const redactor = resolvePiiRedactor(options.piiRedaction);
7013
- const numbered = scope.map((c, i) => {
7014
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
7015
- return `[${i + 1}] ${safe}`;
7016
- }).join("\n");
7013
+ const lines = [];
7014
+ for (const [i, c] of scope.entries()) {
7015
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
7016
+ lines.push(`[${i + 1}] ${safe}`);
7017
+ }
7018
+ const numbered = lines.join("\n");
7017
7019
  let parsed;
7018
7020
  try {
7019
7021
  parsed = await callPortalJsonCompletion({
@@ -7494,7 +7496,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
7494
7496
  content: m.content,
7495
7497
  similarity: m.similarity
7496
7498
  }));
7497
- const { consolidateMemory: doConsolidate } = await import("./consolidate-IFIKT25Z.mjs");
7499
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-POPTUI54.mjs");
7498
7500
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
7499
7501
  if (decision.action === "create") return null;
7500
7502
  if (decision.action === "supersede" && decision.content) {
@@ -8318,7 +8320,7 @@ function createLlmDecayClassifier(options) {
8318
8320
  }
8319
8321
  if (!content || content.trim().length === 0) return ruleVerdict;
8320
8322
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
8321
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
8323
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
8322
8324
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
8323
8325
  let parsed;
8324
8326
  try {
@@ -9052,7 +9054,14 @@ async function synthesizeProfile(ctx, options = {}) {
9052
9054
  observationTrends
9053
9055
  };
9054
9056
  }
9055
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
9057
+ const staleKeys = await computeStaleFacetKeys(
9058
+ ctx,
9059
+ memories,
9060
+ facets,
9061
+ previous,
9062
+ watermark,
9063
+ options.reviewedMemoryIds
9064
+ );
9056
9065
  const settled = await Promise.allSettled(
9057
9066
  facets.map(async (facet) => {
9058
9067
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -9113,7 +9122,7 @@ function computeVaultWatermark(memories) {
9113
9122
  }
9114
9123
  return max;
9115
9124
  }
9116
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
9125
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
9117
9126
  const allKeys = new Set(facets.map((f) => f.key));
9118
9127
  if (previous && watermark < previous.vaultWatermark) return allKeys;
9119
9128
  if (!previous) return allKeys;
@@ -9136,9 +9145,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
9136
9145
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
9137
9146
  }
9138
9147
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
9139
- const toAttribute = changed.filter(
9148
+ let toAttribute = changed.filter(
9140
9149
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
9141
9150
  );
9151
+ if (reviewedMemoryIds !== void 0) {
9152
+ const allowed = new Set(reviewedMemoryIds);
9153
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
9154
+ }
9142
9155
  if (toAttribute.length > 0) {
9143
9156
  const attributed = await attributeFacts(ctx, toAttribute, facets);
9144
9157
  if (attributed === null) return allKeys;
@@ -9415,17 +9428,22 @@ async function extractEntitiesForMemories(memories, options) {
9415
9428
  const out = /* @__PURE__ */ new Map();
9416
9429
  if (memories.length === 0) return out;
9417
9430
  const redactor = resolvePiiRedactor(options.piiRedaction);
9418
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
9431
+ const vocabulary = [];
9432
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
9433
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
9434
+ }
9419
9435
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
9420
9436
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
9421
9437
 
9422
9438
  ` : "";
9423
9439
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
9424
9440
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
9425
- const listing = batch.map((m) => {
9441
+ const rows = [];
9442
+ for (const m of batch) {
9426
9443
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
9427
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
9428
- }).join("\n");
9444
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
9445
+ }
9446
+ const listing = rows.join("\n");
9429
9447
  const parsed = await callPortalJsonCompletion({
9430
9448
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
9431
9449
  ...options.getToken !== void 0 && { getToken: options.getToken },
@@ -55,12 +55,14 @@ async function consolidateMemory(newContent, candidates, options) {
55
55
  if (trimmed.length === 0) return fallback;
56
56
  if (candidates.length === 0) return fallback;
57
57
  const redactor = resolvePiiRedactor(options.piiRedaction);
58
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
59
- const candidateText = candidates.map((c, i) => {
60
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
61
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
62
- ${safeContent}`;
63
- }).join("\n");
58
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
59
+ const rows = [];
60
+ for (const [i, c] of candidates.entries()) {
61
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
62
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
63
+ ${safeContent}`);
64
+ }
65
+ const candidateText = rows.join("\n");
64
66
  const userMessage = `New memory:
65
67
  ${safeTrimmed}
66
68
 
@@ -23580,12 +23580,14 @@ async function consolidateMemory(newContent, candidates, options) {
23580
23580
  if (trimmed.length === 0) return fallback;
23581
23581
  if (candidates.length === 0) return fallback;
23582
23582
  const redactor = resolvePiiRedactor(options.piiRedaction);
23583
- const safeTrimmed = redactor ? redactor.redactText(trimmed).text : trimmed;
23584
- const candidateText = candidates.map((c, i) => {
23585
- const safeContent = redactor ? redactor.redactText(c.content).text : c.content;
23586
- return `[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
23587
- ${safeContent}`;
23588
- }).join("\n");
23583
+ const safeTrimmed = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
23584
+ const rows = [];
23585
+ for (const [i, c] of candidates.entries()) {
23586
+ const safeContent = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
23587
+ rows.push(`[${i + 1}] (id: ${c.id}, sim: ${c.similarity.toFixed(2)})
23588
+ ${safeContent}`);
23589
+ }
23590
+ const candidateText = rows.join("\n");
23589
23591
  const userMessage = `New memory:
23590
23592
  ${safeTrimmed}
23591
23593
 
@@ -28260,10 +28262,12 @@ async function classifyInjectionCandidates(candidates, options) {
28260
28262
  );
28261
28263
  }
28262
28264
  const redactor = resolvePiiRedactor(options.piiRedaction);
28263
- const numbered = scope.map((c, i) => {
28264
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
28265
- return `[${i + 1}] ${safe}`;
28266
- }).join("\n");
28265
+ const lines = [];
28266
+ for (const [i, c] of scope.entries()) {
28267
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
28268
+ lines.push(`[${i + 1}] ${safe}`);
28269
+ }
28270
+ const numbered = lines.join("\n");
28267
28271
  let parsed;
28268
28272
  try {
28269
28273
  parsed = await callPortalJsonCompletion({
@@ -29585,7 +29589,7 @@ function createLlmDecayClassifier(options) {
29585
29589
  }
29586
29590
  if (!content || content.trim().length === 0) return ruleVerdict;
29587
29591
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
29588
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
29592
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
29589
29593
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
29590
29594
  let parsed;
29591
29595
  try {
@@ -30347,7 +30351,14 @@ async function synthesizeProfile(ctx, options = {}) {
30347
30351
  observationTrends
30348
30352
  };
30349
30353
  }
30350
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
30354
+ const staleKeys = await computeStaleFacetKeys(
30355
+ ctx,
30356
+ memories,
30357
+ facets,
30358
+ previous,
30359
+ watermark,
30360
+ options.reviewedMemoryIds
30361
+ );
30351
30362
  const settled = await Promise.allSettled(
30352
30363
  facets.map(async (facet) => {
30353
30364
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -30408,7 +30419,7 @@ function computeVaultWatermark(memories) {
30408
30419
  }
30409
30420
  return max;
30410
30421
  }
30411
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
30422
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
30412
30423
  const allKeys = new Set(facets.map((f) => f.key));
30413
30424
  if (previous && watermark < previous.vaultWatermark) return allKeys;
30414
30425
  if (!previous) return allKeys;
@@ -30431,9 +30442,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
30431
30442
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
30432
30443
  }
30433
30444
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
30434
- const toAttribute = changed.filter(
30445
+ let toAttribute = changed.filter(
30435
30446
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
30436
30447
  );
30448
+ if (reviewedMemoryIds !== void 0) {
30449
+ const allowed = new Set(reviewedMemoryIds);
30450
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
30451
+ }
30437
30452
  if (toAttribute.length > 0) {
30438
30453
  const attributed = await attributeFacts(ctx, toAttribute, facets);
30439
30454
  if (attributed === null) return allKeys;
@@ -30715,17 +30730,22 @@ async function extractEntitiesForMemories(memories, options) {
30715
30730
  const out = /* @__PURE__ */ new Map();
30716
30731
  if (memories.length === 0) return out;
30717
30732
  const redactor = resolvePiiRedactor(options.piiRedaction);
30718
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
30733
+ const vocabulary = [];
30734
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
30735
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
30736
+ }
30719
30737
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
30720
30738
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
30721
30739
 
30722
30740
  ` : "";
30723
30741
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
30724
30742
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
30725
- const listing = batch.map((m) => {
30743
+ const rows = [];
30744
+ for (const m of batch) {
30726
30745
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
30727
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
30728
- }).join("\n");
30746
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
30747
+ }
30748
+ const listing = rows.join("\n");
30729
30749
  const parsed = await callPortalJsonCompletion({
30730
30750
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
30731
30751
  ...options.getToken !== void 0 && { getToken: options.getToken },
@@ -5017,10 +5017,12 @@ async function classifyInjectionCandidates(candidates, options) {
5017
5017
  );
5018
5018
  }
5019
5019
  const redactor = resolvePiiRedactor(options.piiRedaction);
5020
- const numbered = scope.map((c, i) => {
5021
- const safe = redactor ? redactor.redactText(c.content).text : c.content;
5022
- return `[${i + 1}] ${safe}`;
5023
- }).join("\n");
5020
+ const lines = [];
5021
+ for (const [i, c] of scope.entries()) {
5022
+ const safe = redactor ? (await redactor.redactTextAsync(c.content)).text : c.content;
5023
+ lines.push(`[${i + 1}] ${safe}`);
5024
+ }
5025
+ const numbered = lines.join("\n");
5024
5026
  let parsed;
5025
5027
  try {
5026
5028
  parsed = await callPortalJsonCompletion({
@@ -5501,7 +5503,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
5501
5503
  content: m.content,
5502
5504
  similarity: m.similarity
5503
5505
  }));
5504
- const { consolidateMemory: doConsolidate } = await import("./consolidate-GRMEDWKK.mjs");
5506
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-LMIDJFR6.mjs");
5505
5507
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
5506
5508
  if (decision.action === "create") return null;
5507
5509
  if (decision.action === "supersede" && decision.content) {
@@ -6325,7 +6327,7 @@ function createLlmDecayClassifier(options) {
6325
6327
  }
6326
6328
  if (!content || content.trim().length === 0) return ruleVerdict;
6327
6329
  const trimmed = content.trim().slice(0, MAX_CONTENT_CHARS);
6328
- const safe = redactor ? redactor.redactText(trimmed).text : trimmed;
6330
+ const safe = redactor ? (await redactor.redactTextAsync(trimmed)).text : trimmed;
6329
6331
  const meta = `factType: ${input.factType ?? "none"}; ageDays: ${ageDays(input.updatedAt, now)}`;
6330
6332
  let parsed;
6331
6333
  try {
@@ -7059,7 +7061,14 @@ async function synthesizeProfile(ctx, options = {}) {
7059
7061
  observationTrends
7060
7062
  };
7061
7063
  }
7062
- const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
7064
+ const staleKeys = await computeStaleFacetKeys(
7065
+ ctx,
7066
+ memories,
7067
+ facets,
7068
+ previous,
7069
+ watermark,
7070
+ options.reviewedMemoryIds
7071
+ );
7063
7072
  const settled = await Promise.allSettled(
7064
7073
  facets.map(async (facet) => {
7065
7074
  const prior = previous?.sections.find((s) => s.key === facet.key);
@@ -7120,7 +7129,7 @@ function computeVaultWatermark(memories) {
7120
7129
  }
7121
7130
  return max;
7122
7131
  }
7123
- async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark) {
7132
+ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark, reviewedMemoryIds) {
7124
7133
  const allKeys = new Set(facets.map((f) => f.key));
7125
7134
  if (previous && watermark < previous.vaultWatermark) return allKeys;
7126
7135
  if (!previous) return allKeys;
@@ -7143,9 +7152,13 @@ async function computeStaleFacetKeys(ctx, memories, facets, previous, watermark)
7143
7152
  if (!previous.sections.some((s) => s.key === facet.key)) stale.add(facet.key);
7144
7153
  }
7145
7154
  const citedIds = new Set(previous.sections.flatMap((s) => s.sourceMemoryIds));
7146
- const toAttribute = changed.filter(
7155
+ let toAttribute = changed.filter(
7147
7156
  (m) => !m.isDeleted && !m.supersededBy && !citedIds.has(m.uniqueId)
7148
7157
  );
7158
+ if (reviewedMemoryIds !== void 0) {
7159
+ const allowed = new Set(reviewedMemoryIds);
7160
+ toAttribute = toAttribute.filter((m) => allowed.has(m.uniqueId));
7161
+ }
7149
7162
  if (toAttribute.length > 0) {
7150
7163
  const attributed = await attributeFacts(ctx, toAttribute, facets);
7151
7164
  if (attributed === null) return allKeys;
@@ -7422,17 +7435,22 @@ async function extractEntitiesForMemories(memories, options) {
7422
7435
  const out = /* @__PURE__ */ new Map();
7423
7436
  if (memories.length === 0) return out;
7424
7437
  const redactor = resolvePiiRedactor(options.piiRedaction);
7425
- const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
7438
+ const vocabulary = [];
7439
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
7440
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
7441
+ }
7426
7442
  const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
7427
7443
  When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
7428
7444
 
7429
7445
  ` : "";
7430
7446
  for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
7431
7447
  const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
7432
- const listing = batch.map((m) => {
7448
+ const rows = [];
7449
+ for (const m of batch) {
7433
7450
  const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
7434
- return `${m.id}: ${redactor ? redactor.redactText(content).text : content}`;
7435
- }).join("\n");
7451
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
7452
+ }
7453
+ const listing = rows.join("\n");
7436
7454
  const parsed = await callPortalJsonCompletion({
7437
7455
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
7438
7456
  ...options.getToken !== void 0 && { getToken: options.getToken },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "5.0.1",
3
+ "version": "5.0.3",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -136,8 +136,9 @@
136
136
  "lint:fix": "eslint . --fix",
137
137
  "format": "prettier --write .",
138
138
  "format:check": "prettier --check .",
139
- "typecheck": "tsc --noEmit && pnpm run typecheck:test",
139
+ "typecheck": "tsc --noEmit && pnpm run typecheck:test && pnpm run check:excluded-suites",
140
140
  "typecheck:test": "tsc -p tsconfig.test.json",
141
+ "check:excluded-suites": "node scripts/assert-excluded-suites-still-fail.mjs",
141
142
  "knip": "knip",
142
143
  "check:export-consumers": "node scripts/assert-export-consumers.mjs",
143
144
  "check-exports": "publint && attw --pack --ignore-rules no-resolution false-cjs && node scripts/assert-no-client-self-import.mjs",