@anuma/sdk 3.7.0 → 3.8.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.
@@ -5095,10 +5095,10 @@ function injectionSignatureCatalog() {
5095
5095
  }
5096
5096
 
5097
5097
  // src/lib/memory/retain.ts
5098
- var DEFAULT_AUTO_MERGE_THRESHOLD = 0.85;
5098
+ var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
5099
5099
  var DEFAULT_SCOPE = "private";
5100
- var DEFAULT_CONSOLIDATE_THRESHOLD = 0.65;
5101
- var DEFAULT_CONSOLIDATE_TOP_K = 5;
5100
+ var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
5101
+ var DEFAULT_CONSOLIDATE_TOP_K = 20;
5102
5102
  async function retain(content, ctx, options = {}) {
5103
5103
  const trimmed = content.trim();
5104
5104
  if (trimmed.length === 0) {
@@ -5107,18 +5107,18 @@ async function retain(content, ctx, options = {}) {
5107
5107
  const enableAutoMerge = options.enableAutoMerge ?? true;
5108
5108
  const threshold = options.autoMergeThreshold ?? DEFAULT_AUTO_MERGE_THRESHOLD;
5109
5109
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
5110
- let supersedeTargetId;
5110
+ let supersedeTargetIds = [];
5111
5111
  let supersedeContent;
5112
5112
  if (enableAutoMerge) {
5113
5113
  if (options.consolidateOptions) {
5114
5114
  const outcome = await tryConsolidate(trimmed, ctx, options);
5115
5115
  if (outcome) {
5116
5116
  if ("done" in outcome) return outcome.done;
5117
- supersedeTargetId = outcome.supersede;
5117
+ supersedeTargetIds = outcome.supersede;
5118
5118
  supersedeContent = outcome.content;
5119
5119
  }
5120
5120
  }
5121
- if (!supersedeTargetId) {
5121
+ if (supersedeTargetIds.length === 0) {
5122
5122
  const matches = await searchVaultMemories(
5123
5123
  trimmed,
5124
5124
  ctx.vaultCtx,
@@ -5222,18 +5222,42 @@ async function retain(content, ctx, options = {}) {
5222
5222
  // memory's tier. The DB op re-validates against the known set.
5223
5223
  ...options.trustTier !== void 0 && { trustTier: options.trustTier }
5224
5224
  };
5225
- if (supersedeTargetId) {
5225
+ if (supersedeTargetIds.length > 0) {
5226
+ const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
5226
5227
  const { created: created2, retired } = await createSupersedingMemoryOp(
5227
5228
  ctx.vaultCtx,
5228
5229
  createOpts,
5229
- supersedeTargetId
5230
+ primaryTargetId
5230
5231
  );
5231
5232
  if (created2 && retired) {
5232
5233
  ctx.vaultCache.set(created2.uniqueId, Float32Array.from(embedding));
5234
+ const liveLeftovers = [];
5235
+ for (const staleId of restTargetIds) {
5236
+ let ok = false;
5237
+ try {
5238
+ ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
5239
+ } catch {
5240
+ }
5241
+ if (ok) continue;
5242
+ const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
5243
+ if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
5244
+ }
5245
+ if (liveLeftovers.length > 0) {
5246
+ getLogger().warn(
5247
+ "[memory/retain] supersede left duplicate row(s) live \u2014 will reconcile at next consolidation",
5248
+ {
5249
+ newMemoryId: created2.uniqueId,
5250
+ leftover: liveLeftovers.length,
5251
+ // Log the specific ids (opaque record ids, not content) so an
5252
+ // operator can identify exactly which rows are still active.
5253
+ leftoverIds: liveLeftovers
5254
+ }
5255
+ );
5256
+ }
5233
5257
  return {
5234
5258
  action: "supersede",
5235
5259
  memoryId: created2.uniqueId,
5236
- targetId: supersedeTargetId,
5260
+ targetId: primaryTargetId,
5237
5261
  proofCount: 1
5238
5262
  };
5239
5263
  }
@@ -5316,13 +5340,19 @@ async function tryConsolidate(trimmed, ctx, options) {
5316
5340
  content: m.content,
5317
5341
  similarity: m.similarity
5318
5342
  }));
5319
- const { consolidateMemory: doConsolidate } = await import("./consolidate-PCHO3D3G.mjs");
5343
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-BKLNVH5Y.mjs");
5320
5344
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
5321
5345
  if (decision.action === "create") return null;
5322
- if (decision.action === "supersede" && decision.targetId && decision.content) {
5323
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
5324
- if (!existing || existing.supersededBy) return null;
5325
- return { supersede: decision.targetId, content: decision.content };
5346
+ if (decision.action === "supersede" && decision.content) {
5347
+ const requestedIds = decision.targetIds?.length ? decision.targetIds : decision.targetId ? [decision.targetId] : [];
5348
+ if (requestedIds.length === 0) return null;
5349
+ const valid = [];
5350
+ for (const id of requestedIds) {
5351
+ const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
5352
+ if (existing && !existing.supersededBy) valid.push(id);
5353
+ }
5354
+ if (valid.length === 0) return null;
5355
+ return { supersede: valid, content: decision.content };
5326
5356
  }
5327
5357
  if (decision.action === "noop" && decision.targetId) {
5328
5358
  const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
@@ -6593,7 +6623,10 @@ ${evidence}`;
6593
6623
  headers: { ...authHeaders, "Content-Type": "application/json" },
6594
6624
  body: JSON.stringify({
6595
6625
  model,
6596
- max_tokens: maxTokens,
6626
+ // Modern OpenAI field; the portal reads only `max_completion_tokens`
6627
+ // (the deprecated `max_tokens` is silently ignored → falls back to the
6628
+ // portal's default output cap and truncates the answer).
6629
+ max_completion_tokens: maxTokens,
6597
6630
  messages: [
6598
6631
  { role: "system", content: systemPrompt },
6599
6632
  { role: "user", content: userMessage }
@@ -9703,7 +9736,7 @@ var CompletionsStrategy = class {
9703
9736
  model,
9704
9737
  stream,
9705
9738
  ...temperature !== void 0 && { temperature },
9706
- ...maxOutputTokens !== void 0 && { max_tokens: maxOutputTokens },
9739
+ ...maxOutputTokens !== void 0 && { max_completion_tokens: maxOutputTokens },
9707
9740
  ...tools && { tools },
9708
9741
  ...toolChoice && { tool_choice: toolChoice },
9709
9742
  ...portal && { portal }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "3.7.0",
3
+ "version": "3.8.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -139,7 +139,8 @@
139
139
  "knip": "knip",
140
140
  "check-exports": "publint && attw --pack --ignore-rules no-resolution false-cjs && node scripts/assert-no-client-self-import.mjs",
141
141
  "check": "pnpm run lint && pnpm run knip && pnpm run format && pnpm run generate",
142
- "eval:extraction": "tsx test/memory/src/extraction/benchmark.test.ts"
142
+ "eval:extraction": "tsx test/memory/src/extraction/benchmark.test.ts",
143
+ "eval:consolidation": "tsx test/memory/src/consolidation/benchmark.test.ts"
143
144
  },
144
145
  "repository": {
145
146
  "type": "git",
@@ -154,7 +155,7 @@
154
155
  "homepage": "https://github.com/anuma-ai/sdk#readme",
155
156
  "packageManager": "pnpm@10.23.0",
156
157
  "dependencies": {
157
- "@anuma/portal": "1.0.0-next.20260723012206",
158
+ "@anuma/portal": "1.0.0-next.20260724050535",
158
159
  "@babel/parser": "^7.29.2",
159
160
  "@babel/types": "^7.29.0",
160
161
  "ai": "6.0.202",