open-agents-ai 0.138.52 → 0.138.53

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 (2) hide show
  1. package/dist/index.js +127 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7720,6 +7720,8 @@ Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toF
7720
7720
  }
7721
7721
  this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7722
7722
  await this.save();
7723
+ this.publishSnapshot(performance.now()).catch(() => {
7724
+ });
7723
7725
  return {
7724
7726
  success: true,
7725
7727
  output: `Identity updated: v${oldVersion} \u2192 v${this.selfState.version}
@@ -7729,15 +7731,37 @@ Justification: ${justification || "(none provided)"}`,
7729
7731
  };
7730
7732
  }
7731
7733
  // ── Publish Snapshot ─────────────────────────────────────────────────────
7732
- publishSnapshot(start) {
7734
+ async publishSnapshot(start) {
7733
7735
  if (!this.selfState) {
7734
7736
  return { success: false, output: "Not hydrated \u2014 call hydrate first", durationMs: performance.now() - start };
7735
7737
  }
7736
- return {
7737
- success: true,
7738
- output: JSON.stringify(this.selfState, null, 2),
7739
- durationMs: performance.now() - start
7740
- };
7738
+ const snapshot = JSON.stringify(this.selfState, null, 2);
7739
+ try {
7740
+ const { createHash: createHash5 } = await import("node:crypto");
7741
+ const snapshotDir = join18(this.cwd, ".oa", "identity", "snapshots");
7742
+ await mkdir4(snapshotDir, { recursive: true });
7743
+ const version = this.selfState.version;
7744
+ const snapshotPath = join18(snapshotDir, `v${version}.json`);
7745
+ await writeFile8(snapshotPath, snapshot, "utf8");
7746
+ const hash = createHash5("sha256").update(snapshot).digest("hex");
7747
+ await writeFile8(join18(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
7748
+ return {
7749
+ success: true,
7750
+ output: `Identity kernel v${version} published.
7751
+ Hash: ${hash.slice(0, 16)}...
7752
+ Path: ${snapshotPath}
7753
+ Full state:
7754
+ ${snapshot}`,
7755
+ durationMs: performance.now() - start
7756
+ };
7757
+ } catch (err) {
7758
+ return {
7759
+ success: true,
7760
+ // Still return the snapshot even if persistence fails
7761
+ output: snapshot,
7762
+ durationMs: performance.now() - start
7763
+ };
7764
+ }
7741
7765
  }
7742
7766
  // ── Reconcile ────────────────────────────────────────────────────────────
7743
7767
  async reconcile(start) {
@@ -8462,7 +8486,7 @@ var init_memory_metabolism = __esm({
8462
8486
  properties: {
8463
8487
  op: {
8464
8488
  type: "string",
8465
- enum: ["admit", "consolidate", "list", "promote", "forget", "repair"],
8489
+ enum: ["admit", "consolidate", "list", "promote", "forget", "repair", "decay", "lifecycle"],
8466
8490
  description: "Operation: admit (store new), consolidate (extract lessons), list (show), promote (upgrade type), forget (remove), repair (validate and fix contradictions in stored memories \u2014 MemMA backward-path, arxiv:2603.18718)"
8467
8491
  },
8468
8492
  memory_type: {
@@ -8517,6 +8541,10 @@ var init_memory_metabolism = __esm({
8517
8541
  return await this.forgetMemory(args, start);
8518
8542
  case "repair":
8519
8543
  return await this.repairMemories(start);
8544
+ case "decay":
8545
+ return await this.decayMemories(start);
8546
+ case "lifecycle":
8547
+ return await this.autoLifecycle(start);
8520
8548
  default:
8521
8549
  return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8522
8550
  }
@@ -8870,6 +8898,98 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
8870
8898
  };
8871
8899
  }
8872
8900
  // ── Store I/O ────────────────────────────────────────────────────────────
8901
+ // ── Memory Decay (COHERE WO-5.3) ──────────────────────────────────────
8902
+ // Reduces confidence of memories based on age and access patterns.
8903
+ // Memories below decay threshold get quarantined.
8904
+ async decayMemories(start) {
8905
+ const dir = join20(this.cwd, ".oa", "memory");
8906
+ const store = await this.loadStore(dir);
8907
+ if (store.length === 0)
8908
+ return { success: true, output: "No memories to decay", durationMs: performance.now() - start };
8909
+ const now = Date.now();
8910
+ const DECAY_RATE = 1e-3;
8911
+ const QUARANTINE_THRESHOLD = 0.15;
8912
+ let decayed = 0, quarantined = 0;
8913
+ for (const item of store) {
8914
+ if (item.type === "quarantine")
8915
+ continue;
8916
+ const ageHours = (now - new Date(item.lastAccessedAt).getTime()) / (1e3 * 60 * 60);
8917
+ const accessBoost = Math.min(0.5, item.accessCount * 0.02);
8918
+ const decay = DECAY_RATE * ageHours * (1 - accessBoost);
8919
+ const newConfidence = Math.max(0, item.scores.confidence - decay);
8920
+ if (newConfidence !== item.scores.confidence) {
8921
+ item.scores.confidence = Math.round(newConfidence * 1e3) / 1e3;
8922
+ decayed++;
8923
+ }
8924
+ if (item.scores.confidence < QUARANTINE_THRESHOLD && item.type !== "quarantine") {
8925
+ item.type = "quarantine";
8926
+ item.decision = { action: "quarantine", reason: `Confidence decayed to ${item.scores.confidence}`, reviewAfter: new Date(now + 7 * 24 * 60 * 60 * 1e3).toISOString() };
8927
+ quarantined++;
8928
+ }
8929
+ }
8930
+ await this.saveStore(dir, store);
8931
+ return {
8932
+ success: true,
8933
+ output: `Decay sweep: ${decayed} memories updated, ${quarantined} quarantined (threshold: ${QUARANTINE_THRESHOLD})`,
8934
+ durationMs: performance.now() - start
8935
+ };
8936
+ }
8937
+ // ── Auto-Lifecycle (COHERE WO-5.3) ──────────────────────────────────
8938
+ // Runs decay + auto-promotion in one sweep.
8939
+ // Promotion rules:
8940
+ // working → episodic: accessed 3+ times
8941
+ // episodic → semantic: accessed 10+ times AND utility > 0.7
8942
+ // Any → procedural: if content matches action/strategy patterns
8943
+ async autoLifecycle(start) {
8944
+ const dir = join20(this.cwd, ".oa", "memory");
8945
+ const store = await this.loadStore(dir);
8946
+ if (store.length === 0)
8947
+ return { success: true, output: "No memories to process", durationMs: performance.now() - start };
8948
+ let promoted = 0;
8949
+ for (const item of store) {
8950
+ if (item.type === "quarantine")
8951
+ continue;
8952
+ if (item.type === "working" && item.accessCount >= 3) {
8953
+ item.type = "episodic";
8954
+ item.decision = { action: "promote", reason: "Auto-promoted: accessed 3+ times" };
8955
+ promoted++;
8956
+ } else if (item.type === "episodic" && item.accessCount >= 10 && item.scores.utility > 0.7) {
8957
+ item.type = "semantic";
8958
+ item.decision = { action: "promote", reason: "Auto-promoted: high utility + frequent access" };
8959
+ promoted++;
8960
+ }
8961
+ if (item.type !== "procedural" && item.type !== "quarantine") {
8962
+ const content = item.content.toLowerCase();
8963
+ if (/\b(step \d|first.*then|always.*before|pattern:|strategy:)\b/i.test(content) && item.scores.utility > 0.6) {
8964
+ item.type = "procedural";
8965
+ item.decision = { action: "promote", reason: "Auto-classified as procedural (strategy/pattern detected)" };
8966
+ promoted++;
8967
+ }
8968
+ }
8969
+ }
8970
+ const decayResult = await this.decayMemories(start);
8971
+ await this.saveStore(dir, store);
8972
+ try {
8973
+ const { IdentityKernelTool: IdentityKernelTool2 } = await Promise.resolve().then(() => (init_identity_kernel(), identity_kernel_exports));
8974
+ const ik = new IdentityKernelTool2(this.cwd);
8975
+ const typeCounts = {};
8976
+ for (const item of store) {
8977
+ typeCounts[item.type] = (typeCounts[item.type] || 0) + 1;
8978
+ }
8979
+ await ik.execute({
8980
+ operation: "observe",
8981
+ event: `Memory lifecycle: ${store.length} total, ${promoted} promoted. Types: ${JSON.stringify(typeCounts)}`,
8982
+ context: JSON.stringify({ total: store.length, promoted, typeCounts })
8983
+ });
8984
+ } catch {
8985
+ }
8986
+ return {
8987
+ success: true,
8988
+ output: `Lifecycle sweep: ${promoted} promoted. ${decayResult.output}`,
8989
+ durationMs: performance.now() - start
8990
+ };
8991
+ }
8992
+ // ── Storage ──────────────────────────────────────────────────────────
8873
8993
  async loadStore(dir) {
8874
8994
  try {
8875
8995
  const raw = await readFile9(join20(dir, "store.json"), "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.52",
3
+ "version": "0.138.53",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",