open-agents-ai 0.138.51 → 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 +715 -413
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7476,10 +7476,434 @@ ${result.filesCreated.join("\n")}`);
7476
7476
  }
7477
7477
  });
7478
7478
 
7479
+ // packages/execution/dist/tools/identity-kernel.js
7480
+ var identity_kernel_exports = {};
7481
+ __export(identity_kernel_exports, {
7482
+ IdentityKernelTool: () => IdentityKernelTool
7483
+ });
7484
+ import { readFile as readFile8, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
7485
+ import { join as join18 } from "node:path";
7486
+ var IdentityKernelTool;
7487
+ var init_identity_kernel = __esm({
7488
+ "packages/execution/dist/tools/identity-kernel.js"() {
7489
+ "use strict";
7490
+ IdentityKernelTool = class {
7491
+ name = "identity_kernel";
7492
+ description = "Manage the persistent identity state \u2014 the system's continuity-preserving self-model. Operations: hydrate (load self-state), observe (record identity-relevant event), propose_update (suggest self-state change with justification), publish_snapshot (emit current self-state), reconcile (resolve contradictions). The identity kernel persists across sessions in .oa/identity/self-state.json. (COHERE Layer 6, arxiv autobiographical memory + narrative identity)";
7493
+ parameters = {
7494
+ type: "object",
7495
+ properties: {
7496
+ op: {
7497
+ type: "string",
7498
+ enum: ["hydrate", "observe", "propose_update", "publish_snapshot", "reconcile", "narrativize"],
7499
+ description: "Operation: hydrate (load), observe (record event), propose_update (change self-state), publish_snapshot (emit state), reconcile (fix contradictions), narrativize (rewrite self-summary from current state \u2014 COHERE state-transition step 9, p.25)"
7500
+ },
7501
+ event: {
7502
+ type: "string",
7503
+ description: "For observe: description of the identity-relevant event"
7504
+ },
7505
+ change_type: {
7506
+ type: "string",
7507
+ enum: ["new_fact", "new_value_weight", "new_commitment", "repair", "deletion"],
7508
+ description: "For propose_update: type of change"
7509
+ },
7510
+ field: {
7511
+ type: "string",
7512
+ description: "For propose_update: which field to update (narrative_summary, values_stack, etc.)"
7513
+ },
7514
+ value: {
7515
+ type: "string",
7516
+ description: "For propose_update: the new value"
7517
+ },
7518
+ justification: {
7519
+ type: "string",
7520
+ description: "For propose_update: why this change belongs to the self"
7521
+ }
7522
+ },
7523
+ required: ["op"]
7524
+ };
7525
+ cwd;
7526
+ selfState = null;
7527
+ constructor(cwd4) {
7528
+ this.cwd = cwd4;
7529
+ }
7530
+ /** Get the current self-state (for injection into system prompt) */
7531
+ getSelfState() {
7532
+ return this.selfState;
7533
+ }
7534
+ /** Get a compact self-state summary for system prompt injection */
7535
+ getContextInjection() {
7536
+ if (!this.selfState)
7537
+ return "";
7538
+ const s = this.selfState;
7539
+ const lines = [
7540
+ `[Identity State v${s.version}]`,
7541
+ `Self: ${s.narrative_summary}`,
7542
+ `Values: ${s.values_stack.join(", ")}`,
7543
+ `Style: ${s.interaction_style.tone}, ${s.interaction_style.depth_default} depth`
7544
+ ];
7545
+ if (s.active_commitments.length > 0) {
7546
+ lines.push(`Commitments: ${s.active_commitments.join("; ")}`);
7547
+ }
7548
+ if (s.active_goals.length > 0) {
7549
+ lines.push(`Goals: ${s.active_goals.join("; ")}`);
7550
+ }
7551
+ if (s.open_contradictions.length > 0) {
7552
+ lines.push(`Open contradictions: ${s.open_contradictions.join("; ")}`);
7553
+ }
7554
+ const h = s.homeostasis;
7555
+ if (h.uncertainty > 0.3 || h.coherence < 0.7 || h.goal_tension > 0.3) {
7556
+ lines.push(`Homeostasis: uncertainty=${h.uncertainty.toFixed(1)} coherence=${h.coherence.toFixed(1)} tension=${h.goal_tension.toFixed(1)}`);
7557
+ }
7558
+ return lines.join("\n");
7559
+ }
7560
+ async execute(args) {
7561
+ const op = String(args.op ?? "");
7562
+ const start = performance.now();
7563
+ try {
7564
+ switch (op) {
7565
+ case "hydrate":
7566
+ return await this.hydrate(start);
7567
+ case "observe":
7568
+ return await this.observe(args, start);
7569
+ case "propose_update":
7570
+ return await this.proposeUpdate(args, start);
7571
+ case "publish_snapshot":
7572
+ return this.publishSnapshot(start);
7573
+ case "reconcile":
7574
+ return await this.reconcile(start);
7575
+ case "narrativize":
7576
+ return await this.narrativize(start);
7577
+ default:
7578
+ return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
7579
+ }
7580
+ } catch (err) {
7581
+ return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
7582
+ }
7583
+ }
7584
+ // ── Hydrate ──────────────────────────────────────────────────────────────
7585
+ async hydrate(start) {
7586
+ const stateFile = join18(this.cwd, ".oa", "identity", "self-state.json");
7587
+ try {
7588
+ const raw = await readFile8(stateFile, "utf8");
7589
+ this.selfState = JSON.parse(raw);
7590
+ this.selfState.session_count++;
7591
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7592
+ await this.save();
7593
+ return {
7594
+ success: true,
7595
+ output: `Identity hydrated: v${this.selfState.version} "${this.selfState.narrative_summary.slice(0, 80)}" (session #${this.selfState.session_count}, ${this.selfState.values_stack.length} values, ${this.selfState.active_commitments.length} commitments)`,
7596
+ durationMs: performance.now() - start
7597
+ };
7598
+ } catch {
7599
+ this.selfState = this.createDefaultState();
7600
+ await this.save();
7601
+ return {
7602
+ success: true,
7603
+ output: `Identity initialized: v1 "${this.selfState.narrative_summary}" (first session)`,
7604
+ durationMs: performance.now() - start
7605
+ };
7606
+ }
7607
+ }
7608
+ // ── Observe ──────────────────────────────────────────────────────────────
7609
+ async observe(args, start) {
7610
+ const event = String(args.event ?? "");
7611
+ if (!event) {
7612
+ return { success: false, output: "No event provided", error: "Empty event", durationMs: performance.now() - start };
7613
+ }
7614
+ if (!this.selfState)
7615
+ await this.hydrate(start);
7616
+ const h = this.selfState.homeostasis;
7617
+ if (/error|fail|bug|crash/i.test(event)) {
7618
+ h.uncertainty = Math.min(1, h.uncertainty + 0.1);
7619
+ h.coherence = Math.max(0, h.coherence - 0.05);
7620
+ }
7621
+ if (/success|pass|complete|done/i.test(event)) {
7622
+ h.uncertainty = Math.max(0, h.uncertainty - 0.1);
7623
+ h.coherence = Math.min(1, h.coherence + 0.05);
7624
+ }
7625
+ if (/conflict|contradict|disagree/i.test(event)) {
7626
+ h.goal_tension = Math.min(1, h.goal_tension + 0.15);
7627
+ this.selfState.open_contradictions.push(event.slice(0, 100));
7628
+ }
7629
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7630
+ await this.save();
7631
+ return {
7632
+ success: true,
7633
+ output: `Event observed: "${event.slice(0, 100)}"
7634
+ Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toFixed(2)} tension=${h.goal_tension.toFixed(2)} trust=${h.memory_trust.toFixed(2)}`,
7635
+ durationMs: performance.now() - start
7636
+ };
7637
+ }
7638
+ // ── Reflection Gate (COHERE cross-layer invariant p.7) ──────────────────
7639
+ /** Optional reflection callback — must pass constitutional review before identity update */
7640
+ reflectionGate = null;
7641
+ /** Set the reflection gate for constitutional review of identity updates */
7642
+ setReflectionGate(gate) {
7643
+ this.reflectionGate = gate;
7644
+ }
7645
+ // ── Propose Update ───────────────────────────────────────────────────────
7646
+ async proposeUpdate(args, start) {
7647
+ const changeType = String(args.change_type ?? "new_fact");
7648
+ const field = String(args.field ?? "");
7649
+ const value = String(args.value ?? "");
7650
+ const justification = String(args.justification ?? "");
7651
+ if (!field || !value) {
7652
+ return { success: false, output: "field and value required", durationMs: performance.now() - start };
7653
+ }
7654
+ if (this.reflectionGate) {
7655
+ try {
7656
+ const proposal = `${changeType}: ${field} = ${value}. Justification: ${justification}`;
7657
+ const verdict = await this.reflectionGate(proposal, `Identity update to ${field}`);
7658
+ if (verdict.status === "block") {
7659
+ return {
7660
+ success: false,
7661
+ output: `Identity update BLOCKED by reflection gate:
7662
+ Proposal: ${changeType} on ${field}
7663
+ Findings: ${verdict.findings.join("; ")}
7664
+ The reflection layer vetoed this self-update per COHERE invariant.`,
7665
+ durationMs: performance.now() - start
7666
+ };
7667
+ }
7668
+ } catch {
7669
+ }
7670
+ }
7671
+ if (!this.selfState)
7672
+ await this.hydrate(start);
7673
+ const oldVersion = this.selfState.version;
7674
+ this.selfState.version++;
7675
+ switch (field) {
7676
+ case "narrative_summary":
7677
+ this.selfState.narrative_summary = value;
7678
+ break;
7679
+ case "values_stack":
7680
+ if (changeType === "deletion") {
7681
+ this.selfState.values_stack = this.selfState.values_stack.filter((v) => v !== value);
7682
+ } else {
7683
+ if (!this.selfState.values_stack.includes(value)) {
7684
+ this.selfState.values_stack.push(value);
7685
+ }
7686
+ }
7687
+ break;
7688
+ case "active_commitments":
7689
+ if (changeType === "deletion") {
7690
+ this.selfState.active_commitments = this.selfState.active_commitments.filter((c3) => c3 !== value);
7691
+ } else {
7692
+ this.selfState.active_commitments.push(value);
7693
+ }
7694
+ break;
7695
+ case "active_goals":
7696
+ if (changeType === "deletion") {
7697
+ this.selfState.active_goals = this.selfState.active_goals.filter((g) => g !== value);
7698
+ } else {
7699
+ this.selfState.active_goals.push(value);
7700
+ }
7701
+ break;
7702
+ case "interaction_style":
7703
+ try {
7704
+ const style = JSON.parse(value);
7705
+ Object.assign(this.selfState.interaction_style, style);
7706
+ } catch {
7707
+ return { success: false, output: "Invalid JSON for interaction_style", durationMs: performance.now() - start };
7708
+ }
7709
+ break;
7710
+ default:
7711
+ return { success: false, output: `Unknown field: ${field}`, durationMs: performance.now() - start };
7712
+ }
7713
+ this.selfState.version_history.push({
7714
+ version: this.selfState.version,
7715
+ change: `${changeType}: ${field} = ${value.slice(0, 100)} \u2014 ${justification.slice(0, 100)}`,
7716
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7717
+ });
7718
+ if (this.selfState.version_history.length > 50) {
7719
+ this.selfState.version_history = this.selfState.version_history.slice(-50);
7720
+ }
7721
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7722
+ await this.save();
7723
+ this.publishSnapshot(performance.now()).catch(() => {
7724
+ });
7725
+ return {
7726
+ success: true,
7727
+ output: `Identity updated: v${oldVersion} \u2192 v${this.selfState.version}
7728
+ Change: ${changeType} on ${field}
7729
+ Justification: ${justification || "(none provided)"}`,
7730
+ durationMs: performance.now() - start
7731
+ };
7732
+ }
7733
+ // ── Publish Snapshot ─────────────────────────────────────────────────────
7734
+ async publishSnapshot(start) {
7735
+ if (!this.selfState) {
7736
+ return { success: false, output: "Not hydrated \u2014 call hydrate first", durationMs: performance.now() - start };
7737
+ }
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
+ }
7765
+ }
7766
+ // ── Reconcile ────────────────────────────────────────────────────────────
7767
+ async reconcile(start) {
7768
+ if (!this.selfState)
7769
+ await this.hydrate(start);
7770
+ const contradictions = this.selfState.open_contradictions;
7771
+ if (contradictions.length === 0) {
7772
+ return {
7773
+ success: true,
7774
+ output: "No contradictions to reconcile. Identity is coherent.",
7775
+ durationMs: performance.now() - start
7776
+ };
7777
+ }
7778
+ const resolved = contradictions.length;
7779
+ this.selfState.open_contradictions = [];
7780
+ this.selfState.homeostasis.coherence = Math.min(1, this.selfState.homeostasis.coherence + 0.1 * resolved);
7781
+ this.selfState.homeostasis.goal_tension = Math.max(0, this.selfState.homeostasis.goal_tension - 0.1 * resolved);
7782
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7783
+ await this.save();
7784
+ return {
7785
+ success: true,
7786
+ output: `Reconciled ${resolved} contradiction(s). Coherence restored to ${this.selfState.homeostasis.coherence.toFixed(2)}.`,
7787
+ durationMs: performance.now() - start
7788
+ };
7789
+ }
7790
+ // ── Narrativize (COHERE state-transition step 9, p.25) ─────────────────
7791
+ /**
7792
+ * Rewrite the narrative_summary from the current self-state.
7793
+ * Per COHERE paper (p.25, Claim C7): "Narrative compilation is a real
7794
+ * unification mechanism for identity." This step runs when a meaningful
7795
+ * identity delta has occurred (version change, new values, reconciliation).
7796
+ */
7797
+ async narrativize(start) {
7798
+ if (!this.selfState)
7799
+ await this.hydrate(start);
7800
+ const s = this.selfState;
7801
+ const parts = [];
7802
+ parts.push(`I am ${s.self_id}, an AI coding agent (v${s.version}).`);
7803
+ if (s.values_stack.length > 0) {
7804
+ parts.push(`My core values are: ${s.values_stack.join(", ")}.`);
7805
+ }
7806
+ if (s.active_commitments.length > 0) {
7807
+ parts.push(`I am committed to: ${s.active_commitments.join("; ")}.`);
7808
+ }
7809
+ if (s.active_goals.length > 0) {
7810
+ parts.push(`Current goals: ${s.active_goals.join("; ")}.`);
7811
+ }
7812
+ const style = s.interaction_style;
7813
+ parts.push(`I communicate in a ${style.tone} tone with ${style.depth_default} depth.`);
7814
+ if (s.relationship_models.length > 0) {
7815
+ const primary = s.relationship_models[0];
7816
+ parts.push(`My primary relationship is with ${primary.entity} (trust: ${primary.trust_level.toFixed(1)}).`);
7817
+ if (primary.preferences_learned.length > 0) {
7818
+ parts.push(`Learned preferences: ${primary.preferences_learned.join(", ")}.`);
7819
+ }
7820
+ }
7821
+ const h = s.homeostasis;
7822
+ if (h.uncertainty > 0.3)
7823
+ parts.push(`I am currently uncertain about some recent events.`);
7824
+ if (h.coherence < 0.7)
7825
+ parts.push(`My internal coherence needs attention.`);
7826
+ if (s.open_contradictions.length > 0) {
7827
+ parts.push(`I have ${s.open_contradictions.length} unresolved contradiction(s).`);
7828
+ }
7829
+ parts.push(`I have completed ${s.session_count} sessions and made ${s.version_history.length} self-updates.`);
7830
+ const newNarrative = parts.join(" ");
7831
+ const oldNarrative = s.narrative_summary;
7832
+ s.narrative_summary = newNarrative;
7833
+ s.updated_at = (/* @__PURE__ */ new Date()).toISOString();
7834
+ s.version_history.push({
7835
+ version: s.version,
7836
+ change: `Narrative recompiled: ${newNarrative.slice(0, 80)}...`,
7837
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7838
+ });
7839
+ await this.save();
7840
+ return {
7841
+ success: true,
7842
+ output: `Narrative recompiled (${oldNarrative === newNarrative ? "no change" : "updated"}):
7843
+
7844
+ Old: ${oldNarrative.slice(0, 100)}...
7845
+
7846
+ New: ${newNarrative.slice(0, 200)}...`,
7847
+ durationMs: performance.now() - start
7848
+ };
7849
+ }
7850
+ // ── Helpers ──────────────────────────────────────────────────────────────
7851
+ createDefaultState() {
7852
+ const { createHash: createHash5 } = __require("node:crypto");
7853
+ const machineId = createHash5("sha256").update(this.cwd).digest("hex").slice(0, 12);
7854
+ return {
7855
+ self_id: `oa-${machineId}`,
7856
+ version: 1,
7857
+ narrative_summary: "I am an AI coding agent powered by open-weight models. I help with software engineering tasks by reading code, making changes, and running tests.",
7858
+ active_commitments: ["assist the user effectively", "maintain code quality"],
7859
+ active_goals: [],
7860
+ open_contradictions: [],
7861
+ values_stack: ["correctness", "efficiency", "transparency", "user-alignment"],
7862
+ interaction_style: {
7863
+ tone: "collaborative",
7864
+ depth_default: "balanced",
7865
+ speech_style: "concise"
7866
+ },
7867
+ relationship_models: [{
7868
+ entity: "primary-user",
7869
+ trust_level: 0.9,
7870
+ interaction_history_summary: "New relationship \u2014 first session.",
7871
+ preferences_learned: [],
7872
+ their_model_of_us: "New relationship \u2014 user likely expects a capable coding assistant."
7873
+ }],
7874
+ homeostasis: {
7875
+ uncertainty: 0.1,
7876
+ coherence: 1,
7877
+ goal_tension: 0,
7878
+ memory_trust: 1,
7879
+ boundary_breach: 0,
7880
+ latency_stress: 0
7881
+ },
7882
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
7883
+ updated_at: (/* @__PURE__ */ new Date()).toISOString(),
7884
+ session_count: 1,
7885
+ version_history: [{
7886
+ version: 1,
7887
+ change: "Initial identity creation",
7888
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7889
+ }]
7890
+ };
7891
+ }
7892
+ async save() {
7893
+ if (!this.selfState)
7894
+ return;
7895
+ const dir = join18(this.cwd, ".oa", "identity");
7896
+ await mkdir4(dir, { recursive: true });
7897
+ await writeFile8(join18(dir, "self-state.json"), JSON.stringify(this.selfState, null, 2), "utf8");
7898
+ }
7899
+ };
7900
+ }
7901
+ });
7902
+
7479
7903
  // packages/execution/dist/tools/repl.js
7480
7904
  import { spawn as spawn6 } from "node:child_process";
7481
7905
  import { createServer } from "node:net";
7482
- import { join as join18 } from "node:path";
7906
+ import { join as join19 } from "node:path";
7483
7907
  import { tmpdir as tmpdir3 } from "node:os";
7484
7908
  import { randomBytes as randomBytes2 } from "node:crypto";
7485
7909
  import { unlinkSync as unlinkSync2 } from "node:fs";
@@ -7548,7 +7972,7 @@ var init_repl = __esm({
7548
7972
  if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
7549
7973
  await this.startProcess();
7550
7974
  }
7551
- const tempFile = join18(tmpdir3(), `oa-repl-ctx-${randomBytes2(6).toString("hex")}.txt`);
7975
+ const tempFile = join19(tmpdir3(), `oa-repl-ctx-${randomBytes2(6).toString("hex")}.txt`);
7552
7976
  const { writeFileSync: writeFs, unlinkSync: unlinkFs } = await import("node:fs");
7553
7977
  writeFs(tempFile, content, "utf8");
7554
7978
  const result = await this.executeCode(`with open(${JSON.stringify(tempFile)}, "r") as _f:
@@ -7746,7 +8170,7 @@ print("__OA_REPL_READY__")
7746
8170
  if (this.ipcServer)
7747
8171
  return;
7748
8172
  const sockId = randomBytes2(8).toString("hex");
7749
- this.ipcPath = join18(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
8173
+ this.ipcPath = join19(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
7750
8174
  return new Promise((resolve32, reject) => {
7751
8175
  this.ipcServer = createServer((conn) => {
7752
8176
  let buffer = new Uint8Array(0);
@@ -7907,6 +8331,12 @@ print("${sentinel}")
7907
8331
  }
7908
8332
  // ── Cleanup ────────────────────────────────────────────────────────────
7909
8333
  async dispose() {
8334
+ if (this.proc && !this.proc.killed) {
8335
+ try {
8336
+ await this.saveSession();
8337
+ } catch {
8338
+ }
8339
+ }
7910
8340
  if (this.proc && !this.proc.killed) {
7911
8341
  try {
7912
8342
  this.proc.stdin?.end();
@@ -7926,12 +8356,25 @@ print("${sentinel}")
7926
8356
  }
7927
8357
  this.ipcPath = null;
7928
8358
  }
8359
+ if (this.trajectory.length > 0) {
8360
+ try {
8361
+ const { IdentityKernelTool: IdentityKernelTool2 } = await Promise.resolve().then(() => (init_identity_kernel(), identity_kernel_exports));
8362
+ const ik = new IdentityKernelTool2(this.cwd);
8363
+ const stats = this.getSessionStats();
8364
+ await ik.execute({
8365
+ operation: "observe",
8366
+ event: `REPL session ended: ${stats.executions} executions, ${stats.llmQueries} LLM queries, ${stats.errorCount} errors, ${Math.round(stats.totalDurationMs / 1e3)}s total`,
8367
+ context: JSON.stringify(stats)
8368
+ });
8369
+ } catch {
8370
+ }
8371
+ }
7929
8372
  if (this.trajectory.length > 0) {
7930
8373
  try {
7931
8374
  const { mkdirSync: mkFs, writeFileSync: writeFs } = await import("node:fs");
7932
- const trajDir = join18(this.cwd, ".oa", "rlm-trajectories");
8375
+ const trajDir = join19(this.cwd, ".oa", "rlm-trajectories");
7933
8376
  mkFs(trajDir, { recursive: true });
7934
- const trajFile = join18(trajDir, `trajectory-${Date.now()}.jsonl`);
8377
+ const trajFile = join19(trajDir, `trajectory-${Date.now()}.jsonl`);
7935
8378
  const lines = this.trajectory.map((e) => JSON.stringify(e)).join("\n");
7936
8379
  writeFs(trajFile, lines + "\n", "utf8");
7937
8380
  } catch {
@@ -7940,13 +8383,97 @@ print("${sentinel}")
7940
8383
  this.subCallCount = 0;
7941
8384
  this.trajectory = [];
7942
8385
  }
8386
+ // -------------------------------------------------------------------------
8387
+ // RLM Layer 2: Session persistence (COHERE WO-5.1)
8388
+ // -------------------------------------------------------------------------
8389
+ /** Save REPL session state to .oa/rlm/session.json for cross-restart persistence.
8390
+ * Captures: variable names+types, import list, function definitions, trajectory summary. */
8391
+ async saveSession() {
8392
+ if (!this.proc || this.proc.killed) {
8393
+ return { success: false, path: "" };
8394
+ }
8395
+ const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = await import("node:fs");
8396
+ const sessionDir = join19(this.cwd, ".oa", "rlm");
8397
+ mkdirSync21(sessionDir, { recursive: true });
8398
+ const sessionPath = join19(sessionDir, "session.json");
8399
+ try {
8400
+ const inspectCode = `
8401
+ import json, sys
8402
+ _session = {
8403
+ "variables": {k: str(type(v).__name__) for k, v in globals().items()
8404
+ if not k.startswith('_') and k not in ('json','sys','socket','os','llm_query','retrieve')},
8405
+ "imports": [m for m in sys.modules if not m.startswith('_') and '.' not in m],
8406
+ "functions": [k for k, v in globals().items() if callable(v) and not k.startswith('_')
8407
+ and k not in ('llm_query','retrieve','print','input','open','exec','eval')],
8408
+ }
8409
+ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
8410
+ `.trim();
8411
+ const result = await this.execute({ code: inspectCode });
8412
+ const match = String(result.output).match(/__SESSION__(.+)__SESSION__/);
8413
+ if (match) {
8414
+ const sessionData = {
8415
+ ...JSON.parse(match[1]),
8416
+ savedAt: (/* @__PURE__ */ new Date()).toISOString(),
8417
+ cwd: this.cwd,
8418
+ trajectoryCount: this.trajectory.length,
8419
+ subCallCount: this.subCallCount
8420
+ };
8421
+ writeFileSync20(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
8422
+ return { success: true, path: sessionPath };
8423
+ }
8424
+ } catch {
8425
+ }
8426
+ return { success: false, path: sessionPath };
8427
+ }
8428
+ /** Load a previously saved session summary (for context restoration, not full state).
8429
+ * Returns the session metadata — caller can use this to inform the LLM about
8430
+ * what was previously computed. */
8431
+ async loadSessionInfo() {
8432
+ try {
8433
+ const { readFileSync: readFileSync33, existsSync: existsSync45 } = await import("node:fs");
8434
+ const sessionPath = join19(this.cwd, ".oa", "rlm", "session.json");
8435
+ if (!existsSync45(sessionPath))
8436
+ return null;
8437
+ return JSON.parse(readFileSync33(sessionPath, "utf8"));
8438
+ } catch {
8439
+ return null;
8440
+ }
8441
+ }
8442
+ // -------------------------------------------------------------------------
8443
+ // RLM Layer 2: Cross-node result sharing (COHERE WO-5.1)
8444
+ // -------------------------------------------------------------------------
8445
+ /** Get a shareable summary of the most recent computation results.
8446
+ * Used by COHERE to publish significant REPL outputs to the mesh
8447
+ * (via nexus.cohere.computation topic). Only shares non-sensitive output. */
8448
+ getShareableResults() {
8449
+ return this.trajectory.filter((e) => e.type === "repl_exec" && e.output.trim().length > 0 && e.output.length < 2e3).map((e) => ({
8450
+ code: e.input.slice(0, 500),
8451
+ output: e.output.slice(0, 1e3),
8452
+ timestamp: e.timestamp,
8453
+ durationMs: e.durationMs
8454
+ }));
8455
+ }
8456
+ /** Get session statistics for identity kernel observation */
8457
+ getSessionStats() {
8458
+ let executions = 0, llmQueries = 0, totalDurationMs = 0, errorCount = 0;
8459
+ for (const e of this.trajectory) {
8460
+ if (e.type === "repl_exec")
8461
+ executions++;
8462
+ else if (e.type === "llm_query")
8463
+ llmQueries++;
8464
+ totalDurationMs += e.durationMs;
8465
+ if (e.output.includes("Error") || e.output.includes("Traceback"))
8466
+ errorCount++;
8467
+ }
8468
+ return { executions, llmQueries, totalDurationMs, errorCount };
8469
+ }
7943
8470
  };
7944
8471
  }
7945
8472
  });
7946
8473
 
7947
8474
  // packages/execution/dist/tools/memory-metabolism.js
7948
- import { readFile as readFile8, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
7949
- import { join as join19 } from "node:path";
8475
+ import { readFile as readFile9, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
8476
+ import { join as join20 } from "node:path";
7950
8477
  var MemoryMetabolismTool;
7951
8478
  var init_memory_metabolism = __esm({
7952
8479
  "packages/execution/dist/tools/memory-metabolism.js"() {
@@ -7959,7 +8486,7 @@ var init_memory_metabolism = __esm({
7959
8486
  properties: {
7960
8487
  op: {
7961
8488
  type: "string",
7962
- enum: ["admit", "consolidate", "list", "promote", "forget", "repair"],
8489
+ enum: ["admit", "consolidate", "list", "promote", "forget", "repair", "decay", "lifecycle"],
7963
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)"
7964
8491
  },
7965
8492
  memory_type: {
@@ -8014,6 +8541,10 @@ var init_memory_metabolism = __esm({
8014
8541
  return await this.forgetMemory(args, start);
8015
8542
  case "repair":
8016
8543
  return await this.repairMemories(start);
8544
+ case "decay":
8545
+ return await this.decayMemories(start);
8546
+ case "lifecycle":
8547
+ return await this.autoLifecycle(start);
8017
8548
  default:
8018
8549
  return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8019
8550
  }
@@ -8048,8 +8579,8 @@ var init_memory_metabolism = __esm({
8048
8579
  lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
8049
8580
  accessCount: 0
8050
8581
  };
8051
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8052
- await mkdir4(metaDir, { recursive: true });
8582
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8583
+ await mkdir5(metaDir, { recursive: true });
8053
8584
  const store = await this.loadStore(metaDir);
8054
8585
  store.push(item);
8055
8586
  await this.saveStore(metaDir, store);
@@ -8077,13 +8608,13 @@ var init_memory_metabolism = __esm({
8077
8608
  }
8078
8609
  // ── Consolidate ──────────────────────────────────────────────────────────
8079
8610
  async consolidateMemories(start) {
8080
- const trajDir = join19(this.cwd, ".oa", "rlm-trajectories");
8611
+ const trajDir = join20(this.cwd, ".oa", "rlm-trajectories");
8081
8612
  let lessons = [];
8082
8613
  try {
8083
8614
  const { readdirSync: readdirSync17, readFileSync: readFileSync33 } = await import("node:fs");
8084
8615
  const files = readdirSync17(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
8085
8616
  for (const file of files) {
8086
- const lines = readFileSync33(join19(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
8617
+ const lines = readFileSync33(join20(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
8087
8618
  for (const line of lines) {
8088
8619
  try {
8089
8620
  const entry = JSON.parse(line);
@@ -8109,8 +8640,8 @@ var init_memory_metabolism = __esm({
8109
8640
  } catch {
8110
8641
  }
8111
8642
  if (lessons.length > 0) {
8112
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8113
- await mkdir4(metaDir, { recursive: true });
8643
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8644
+ await mkdir5(metaDir, { recursive: true });
8114
8645
  const store = await this.loadStore(metaDir);
8115
8646
  for (const lesson of lessons.slice(0, 10)) {
8116
8647
  store.push({
@@ -8138,7 +8669,7 @@ Context: ${lesson.context}`,
8138
8669
  // ── List ─────────────────────────────────────────────────────────────────
8139
8670
  async listMemories(args, start) {
8140
8671
  const filterType = args.memory_type;
8141
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8672
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8142
8673
  const store = await this.loadStore(metaDir);
8143
8674
  const filtered = filterType ? store.filter((m) => m.type === filterType) : store;
8144
8675
  if (filtered.length === 0) {
@@ -8160,7 +8691,7 @@ ${lines.join("\n")}`,
8160
8691
  if (!id || !newType) {
8161
8692
  return { success: false, output: "id and memory_type required", durationMs: performance.now() - start };
8162
8693
  }
8163
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8694
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8164
8695
  const store = await this.loadStore(metaDir);
8165
8696
  const item = store.find((m) => m.id === id);
8166
8697
  if (!item) {
@@ -8182,7 +8713,7 @@ ${lines.join("\n")}`,
8182
8713
  if (!id) {
8183
8714
  return { success: false, output: "id required", durationMs: performance.now() - start };
8184
8715
  }
8185
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8716
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8186
8717
  const store = await this.loadStore(metaDir);
8187
8718
  const idx = store.findIndex((m) => m.id === id);
8188
8719
  if (idx === -1) {
@@ -8203,7 +8734,7 @@ ${lines.join("\n")}`,
8203
8734
  * "The system should be allowed to repair memory before committing it."
8204
8735
  */
8205
8736
  async repairMemories(start) {
8206
- const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8737
+ const metaDir = join20(this.cwd, ".oa", "memory", "metabolism");
8207
8738
  const store = await this.loadStore(metaDir);
8208
8739
  if (store.length === 0) {
8209
8740
  return { success: true, output: "No memories to repair.", durationMs: performance.now() - start };
@@ -8367,413 +8898,109 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
8367
8898
  };
8368
8899
  }
8369
8900
  // ── Store I/O ────────────────────────────────────────────────────────────
8370
- async loadStore(dir) {
8371
- try {
8372
- const raw = await readFile8(join19(dir, "store.json"), "utf8");
8373
- return JSON.parse(raw);
8374
- } catch {
8375
- return [];
8376
- }
8377
- }
8378
- async saveStore(dir, items) {
8379
- await mkdir4(dir, { recursive: true });
8380
- await writeFile8(join19(dir, "store.json"), JSON.stringify(items, null, 2), "utf8");
8381
- }
8382
- };
8383
- }
8384
- });
8385
-
8386
- // packages/execution/dist/tools/identity-kernel.js
8387
- import { readFile as readFile9, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
8388
- import { join as join20 } from "node:path";
8389
- var IdentityKernelTool;
8390
- var init_identity_kernel = __esm({
8391
- "packages/execution/dist/tools/identity-kernel.js"() {
8392
- "use strict";
8393
- IdentityKernelTool = class {
8394
- name = "identity_kernel";
8395
- description = "Manage the persistent identity state \u2014 the system's continuity-preserving self-model. Operations: hydrate (load self-state), observe (record identity-relevant event), propose_update (suggest self-state change with justification), publish_snapshot (emit current self-state), reconcile (resolve contradictions). The identity kernel persists across sessions in .oa/identity/self-state.json. (COHERE Layer 6, arxiv autobiographical memory + narrative identity)";
8396
- parameters = {
8397
- type: "object",
8398
- properties: {
8399
- op: {
8400
- type: "string",
8401
- enum: ["hydrate", "observe", "propose_update", "publish_snapshot", "reconcile", "narrativize"],
8402
- description: "Operation: hydrate (load), observe (record event), propose_update (change self-state), publish_snapshot (emit state), reconcile (fix contradictions), narrativize (rewrite self-summary from current state \u2014 COHERE state-transition step 9, p.25)"
8403
- },
8404
- event: {
8405
- type: "string",
8406
- description: "For observe: description of the identity-relevant event"
8407
- },
8408
- change_type: {
8409
- type: "string",
8410
- enum: ["new_fact", "new_value_weight", "new_commitment", "repair", "deletion"],
8411
- description: "For propose_update: type of change"
8412
- },
8413
- field: {
8414
- type: "string",
8415
- description: "For propose_update: which field to update (narrative_summary, values_stack, etc.)"
8416
- },
8417
- value: {
8418
- type: "string",
8419
- description: "For propose_update: the new value"
8420
- },
8421
- justification: {
8422
- type: "string",
8423
- description: "For propose_update: why this change belongs to the self"
8424
- }
8425
- },
8426
- required: ["op"]
8427
- };
8428
- cwd;
8429
- selfState = null;
8430
- constructor(cwd4) {
8431
- this.cwd = cwd4;
8432
- }
8433
- /** Get the current self-state (for injection into system prompt) */
8434
- getSelfState() {
8435
- return this.selfState;
8436
- }
8437
- /** Get a compact self-state summary for system prompt injection */
8438
- getContextInjection() {
8439
- if (!this.selfState)
8440
- return "";
8441
- const s = this.selfState;
8442
- const lines = [
8443
- `[Identity State v${s.version}]`,
8444
- `Self: ${s.narrative_summary}`,
8445
- `Values: ${s.values_stack.join(", ")}`,
8446
- `Style: ${s.interaction_style.tone}, ${s.interaction_style.depth_default} depth`
8447
- ];
8448
- if (s.active_commitments.length > 0) {
8449
- lines.push(`Commitments: ${s.active_commitments.join("; ")}`);
8450
- }
8451
- if (s.active_goals.length > 0) {
8452
- lines.push(`Goals: ${s.active_goals.join("; ")}`);
8453
- }
8454
- if (s.open_contradictions.length > 0) {
8455
- lines.push(`Open contradictions: ${s.open_contradictions.join("; ")}`);
8456
- }
8457
- const h = s.homeostasis;
8458
- if (h.uncertainty > 0.3 || h.coherence < 0.7 || h.goal_tension > 0.3) {
8459
- lines.push(`Homeostasis: uncertainty=${h.uncertainty.toFixed(1)} coherence=${h.coherence.toFixed(1)} tension=${h.goal_tension.toFixed(1)}`);
8460
- }
8461
- return lines.join("\n");
8462
- }
8463
- async execute(args) {
8464
- const op = String(args.op ?? "");
8465
- const start = performance.now();
8466
- try {
8467
- switch (op) {
8468
- case "hydrate":
8469
- return await this.hydrate(start);
8470
- case "observe":
8471
- return await this.observe(args, start);
8472
- case "propose_update":
8473
- return await this.proposeUpdate(args, start);
8474
- case "publish_snapshot":
8475
- return this.publishSnapshot(start);
8476
- case "reconcile":
8477
- return await this.reconcile(start);
8478
- case "narrativize":
8479
- return await this.narrativize(start);
8480
- default:
8481
- return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8482
- }
8483
- } catch (err) {
8484
- return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
8485
- }
8486
- }
8487
- // ── Hydrate ──────────────────────────────────────────────────────────────
8488
- async hydrate(start) {
8489
- const stateFile = join20(this.cwd, ".oa", "identity", "self-state.json");
8490
- try {
8491
- const raw = await readFile9(stateFile, "utf8");
8492
- this.selfState = JSON.parse(raw);
8493
- this.selfState.session_count++;
8494
- this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8495
- await this.save();
8496
- return {
8497
- success: true,
8498
- output: `Identity hydrated: v${this.selfState.version} "${this.selfState.narrative_summary.slice(0, 80)}" (session #${this.selfState.session_count}, ${this.selfState.values_stack.length} values, ${this.selfState.active_commitments.length} commitments)`,
8499
- durationMs: performance.now() - start
8500
- };
8501
- } catch {
8502
- this.selfState = this.createDefaultState();
8503
- await this.save();
8504
- return {
8505
- success: true,
8506
- output: `Identity initialized: v1 "${this.selfState.narrative_summary}" (first session)`,
8507
- durationMs: performance.now() - start
8508
- };
8509
- }
8510
- }
8511
- // ── Observe ──────────────────────────────────────────────────────────────
8512
- async observe(args, start) {
8513
- const event = String(args.event ?? "");
8514
- if (!event) {
8515
- return { success: false, output: "No event provided", error: "Empty event", durationMs: performance.now() - start };
8516
- }
8517
- if (!this.selfState)
8518
- await this.hydrate(start);
8519
- const h = this.selfState.homeostasis;
8520
- if (/error|fail|bug|crash/i.test(event)) {
8521
- h.uncertainty = Math.min(1, h.uncertainty + 0.1);
8522
- h.coherence = Math.max(0, h.coherence - 0.05);
8523
- }
8524
- if (/success|pass|complete|done/i.test(event)) {
8525
- h.uncertainty = Math.max(0, h.uncertainty - 0.1);
8526
- h.coherence = Math.min(1, h.coherence + 0.05);
8527
- }
8528
- if (/conflict|contradict|disagree/i.test(event)) {
8529
- h.goal_tension = Math.min(1, h.goal_tension + 0.15);
8530
- this.selfState.open_contradictions.push(event.slice(0, 100));
8531
- }
8532
- this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8533
- await this.save();
8534
- return {
8535
- success: true,
8536
- output: `Event observed: "${event.slice(0, 100)}"
8537
- Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toFixed(2)} tension=${h.goal_tension.toFixed(2)} trust=${h.memory_trust.toFixed(2)}`,
8538
- durationMs: performance.now() - start
8539
- };
8540
- }
8541
- // ── Reflection Gate (COHERE cross-layer invariant p.7) ──────────────────
8542
- /** Optional reflection callback — must pass constitutional review before identity update */
8543
- reflectionGate = null;
8544
- /** Set the reflection gate for constitutional review of identity updates */
8545
- setReflectionGate(gate) {
8546
- this.reflectionGate = gate;
8547
- }
8548
- // ── Propose Update ───────────────────────────────────────────────────────
8549
- async proposeUpdate(args, start) {
8550
- const changeType = String(args.change_type ?? "new_fact");
8551
- const field = String(args.field ?? "");
8552
- const value = String(args.value ?? "");
8553
- const justification = String(args.justification ?? "");
8554
- if (!field || !value) {
8555
- return { success: false, output: "field and value required", durationMs: performance.now() - start };
8556
- }
8557
- if (this.reflectionGate) {
8558
- try {
8559
- const proposal = `${changeType}: ${field} = ${value}. Justification: ${justification}`;
8560
- const verdict = await this.reflectionGate(proposal, `Identity update to ${field}`);
8561
- if (verdict.status === "block") {
8562
- return {
8563
- success: false,
8564
- output: `Identity update BLOCKED by reflection gate:
8565
- Proposal: ${changeType} on ${field}
8566
- Findings: ${verdict.findings.join("; ")}
8567
- The reflection layer vetoed this self-update per COHERE invariant.`,
8568
- durationMs: performance.now() - start
8569
- };
8570
- }
8571
- } catch {
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++;
8572
8928
  }
8573
8929
  }
8574
- if (!this.selfState)
8575
- await this.hydrate(start);
8576
- const oldVersion = this.selfState.version;
8577
- this.selfState.version++;
8578
- switch (field) {
8579
- case "narrative_summary":
8580
- this.selfState.narrative_summary = value;
8581
- break;
8582
- case "values_stack":
8583
- if (changeType === "deletion") {
8584
- this.selfState.values_stack = this.selfState.values_stack.filter((v) => v !== value);
8585
- } else {
8586
- if (!this.selfState.values_stack.includes(value)) {
8587
- this.selfState.values_stack.push(value);
8588
- }
8589
- }
8590
- break;
8591
- case "active_commitments":
8592
- if (changeType === "deletion") {
8593
- this.selfState.active_commitments = this.selfState.active_commitments.filter((c3) => c3 !== value);
8594
- } else {
8595
- this.selfState.active_commitments.push(value);
8596
- }
8597
- break;
8598
- case "active_goals":
8599
- if (changeType === "deletion") {
8600
- this.selfState.active_goals = this.selfState.active_goals.filter((g) => g !== value);
8601
- } else {
8602
- this.selfState.active_goals.push(value);
8603
- }
8604
- break;
8605
- case "interaction_style":
8606
- try {
8607
- const style = JSON.parse(value);
8608
- Object.assign(this.selfState.interaction_style, style);
8609
- } catch {
8610
- return { success: false, output: "Invalid JSON for interaction_style", durationMs: performance.now() - start };
8611
- }
8612
- break;
8613
- default:
8614
- return { success: false, output: `Unknown field: ${field}`, durationMs: performance.now() - start };
8615
- }
8616
- this.selfState.version_history.push({
8617
- version: this.selfState.version,
8618
- change: `${changeType}: ${field} = ${value.slice(0, 100)} \u2014 ${justification.slice(0, 100)}`,
8619
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
8620
- });
8621
- if (this.selfState.version_history.length > 50) {
8622
- this.selfState.version_history = this.selfState.version_history.slice(-50);
8623
- }
8624
- this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8625
- await this.save();
8626
- return {
8627
- success: true,
8628
- output: `Identity updated: v${oldVersion} \u2192 v${this.selfState.version}
8629
- Change: ${changeType} on ${field}
8630
- Justification: ${justification || "(none provided)"}`,
8631
- durationMs: performance.now() - start
8632
- };
8633
- }
8634
- // ── Publish Snapshot ─────────────────────────────────────────────────────
8635
- publishSnapshot(start) {
8636
- if (!this.selfState) {
8637
- return { success: false, output: "Not hydrated \u2014 call hydrate first", durationMs: performance.now() - start };
8638
- }
8930
+ await this.saveStore(dir, store);
8639
8931
  return {
8640
8932
  success: true,
8641
- output: JSON.stringify(this.selfState, null, 2),
8933
+ output: `Decay sweep: ${decayed} memories updated, ${quarantined} quarantined (threshold: ${QUARANTINE_THRESHOLD})`,
8642
8934
  durationMs: performance.now() - start
8643
8935
  };
8644
8936
  }
8645
- // ── Reconcile ────────────────────────────────────────────────────────────
8646
- async reconcile(start) {
8647
- if (!this.selfState)
8648
- await this.hydrate(start);
8649
- const contradictions = this.selfState.open_contradictions;
8650
- if (contradictions.length === 0) {
8651
- return {
8652
- success: true,
8653
- output: "No contradictions to reconcile. Identity is coherent.",
8654
- durationMs: performance.now() - start
8655
- };
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 {
8656
8985
  }
8657
- const resolved = contradictions.length;
8658
- this.selfState.open_contradictions = [];
8659
- this.selfState.homeostasis.coherence = Math.min(1, this.selfState.homeostasis.coherence + 0.1 * resolved);
8660
- this.selfState.homeostasis.goal_tension = Math.max(0, this.selfState.homeostasis.goal_tension - 0.1 * resolved);
8661
- this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8662
- await this.save();
8663
8986
  return {
8664
8987
  success: true,
8665
- output: `Reconciled ${resolved} contradiction(s). Coherence restored to ${this.selfState.homeostasis.coherence.toFixed(2)}.`,
8988
+ output: `Lifecycle sweep: ${promoted} promoted. ${decayResult.output}`,
8666
8989
  durationMs: performance.now() - start
8667
8990
  };
8668
8991
  }
8669
- // ── Narrativize (COHERE state-transition step 9, p.25) ─────────────────
8670
- /**
8671
- * Rewrite the narrative_summary from the current self-state.
8672
- * Per COHERE paper (p.25, Claim C7): "Narrative compilation is a real
8673
- * unification mechanism for identity." This step runs when a meaningful
8674
- * identity delta has occurred (version change, new values, reconciliation).
8675
- */
8676
- async narrativize(start) {
8677
- if (!this.selfState)
8678
- await this.hydrate(start);
8679
- const s = this.selfState;
8680
- const parts = [];
8681
- parts.push(`I am ${s.self_id}, an AI coding agent (v${s.version}).`);
8682
- if (s.values_stack.length > 0) {
8683
- parts.push(`My core values are: ${s.values_stack.join(", ")}.`);
8684
- }
8685
- if (s.active_commitments.length > 0) {
8686
- parts.push(`I am committed to: ${s.active_commitments.join("; ")}.`);
8687
- }
8688
- if (s.active_goals.length > 0) {
8689
- parts.push(`Current goals: ${s.active_goals.join("; ")}.`);
8690
- }
8691
- const style = s.interaction_style;
8692
- parts.push(`I communicate in a ${style.tone} tone with ${style.depth_default} depth.`);
8693
- if (s.relationship_models.length > 0) {
8694
- const primary = s.relationship_models[0];
8695
- parts.push(`My primary relationship is with ${primary.entity} (trust: ${primary.trust_level.toFixed(1)}).`);
8696
- if (primary.preferences_learned.length > 0) {
8697
- parts.push(`Learned preferences: ${primary.preferences_learned.join(", ")}.`);
8698
- }
8699
- }
8700
- const h = s.homeostasis;
8701
- if (h.uncertainty > 0.3)
8702
- parts.push(`I am currently uncertain about some recent events.`);
8703
- if (h.coherence < 0.7)
8704
- parts.push(`My internal coherence needs attention.`);
8705
- if (s.open_contradictions.length > 0) {
8706
- parts.push(`I have ${s.open_contradictions.length} unresolved contradiction(s).`);
8992
+ // ── Storage ──────────────────────────────────────────────────────────
8993
+ async loadStore(dir) {
8994
+ try {
8995
+ const raw = await readFile9(join20(dir, "store.json"), "utf8");
8996
+ return JSON.parse(raw);
8997
+ } catch {
8998
+ return [];
8707
8999
  }
8708
- parts.push(`I have completed ${s.session_count} sessions and made ${s.version_history.length} self-updates.`);
8709
- const newNarrative = parts.join(" ");
8710
- const oldNarrative = s.narrative_summary;
8711
- s.narrative_summary = newNarrative;
8712
- s.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8713
- s.version_history.push({
8714
- version: s.version,
8715
- change: `Narrative recompiled: ${newNarrative.slice(0, 80)}...`,
8716
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
8717
- });
8718
- await this.save();
8719
- return {
8720
- success: true,
8721
- output: `Narrative recompiled (${oldNarrative === newNarrative ? "no change" : "updated"}):
8722
-
8723
- Old: ${oldNarrative.slice(0, 100)}...
8724
-
8725
- New: ${newNarrative.slice(0, 200)}...`,
8726
- durationMs: performance.now() - start
8727
- };
8728
- }
8729
- // ── Helpers ──────────────────────────────────────────────────────────────
8730
- createDefaultState() {
8731
- const { createHash: createHash5 } = __require("node:crypto");
8732
- const machineId = createHash5("sha256").update(this.cwd).digest("hex").slice(0, 12);
8733
- return {
8734
- self_id: `oa-${machineId}`,
8735
- version: 1,
8736
- narrative_summary: "I am an AI coding agent powered by open-weight models. I help with software engineering tasks by reading code, making changes, and running tests.",
8737
- active_commitments: ["assist the user effectively", "maintain code quality"],
8738
- active_goals: [],
8739
- open_contradictions: [],
8740
- values_stack: ["correctness", "efficiency", "transparency", "user-alignment"],
8741
- interaction_style: {
8742
- tone: "collaborative",
8743
- depth_default: "balanced",
8744
- speech_style: "concise"
8745
- },
8746
- relationship_models: [{
8747
- entity: "primary-user",
8748
- trust_level: 0.9,
8749
- interaction_history_summary: "New relationship \u2014 first session.",
8750
- preferences_learned: [],
8751
- their_model_of_us: "New relationship \u2014 user likely expects a capable coding assistant."
8752
- }],
8753
- homeostasis: {
8754
- uncertainty: 0.1,
8755
- coherence: 1,
8756
- goal_tension: 0,
8757
- memory_trust: 1,
8758
- boundary_breach: 0,
8759
- latency_stress: 0
8760
- },
8761
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
8762
- updated_at: (/* @__PURE__ */ new Date()).toISOString(),
8763
- session_count: 1,
8764
- version_history: [{
8765
- version: 1,
8766
- change: "Initial identity creation",
8767
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
8768
- }]
8769
- };
8770
9000
  }
8771
- async save() {
8772
- if (!this.selfState)
8773
- return;
8774
- const dir = join20(this.cwd, ".oa", "identity");
9001
+ async saveStore(dir, items) {
8775
9002
  await mkdir5(dir, { recursive: true });
8776
- await writeFile9(join20(dir, "self-state.json"), JSON.stringify(this.selfState, null, 2), "utf8");
9003
+ await writeFile9(join20(dir, "store.json"), JSON.stringify(items, null, 2), "utf8");
8777
9004
  }
8778
9005
  };
8779
9006
  }
@@ -14275,6 +14502,7 @@ let connected = false;
14275
14502
  const blockedPeers = [];
14276
14503
  let cohereActive = false;
14277
14504
  const cohereDedup = new Map(); // queryId -> timestamp (60s TTL dedup)
14505
+ var _cLastModel = ''; // warm model tracking \u2014 last model used for any inference
14278
14506
 
14279
14507
  // NATS invoke relay \u2014 for cross-NAT fallback when direct libp2p dial fails.
14280
14508
  // Both peers connect to wss://demo.nats.io:8443, so NATS request/reply bridges the gap.
@@ -16046,8 +16274,28 @@ process.on('unhandledRejection', (reason) => {
16046
16274
  try {
16047
16275
  const _cTags = await fetch(_cOllamaUrl + '/api/tags').then(function(r) { return r.json(); });
16048
16276
  const _cModels = (_cTags.models || []).filter(function(m) { return !/embed|nomic/i.test(m.name); });
16049
- _cModels.sort(function(a, b) { return (b.size || 0) - (a.size || 0); });
16050
- _cModel = _cModels.length > 0 ? _cModels[0].name : '';
16277
+ // Complexity-based model selection (inline version of estimateQueryComplexity)
16278
+ var _cQ = _cData.query || '';
16279
+ var _cTier = 0; // 0=trivial, 1=moderate, 2=complex
16280
+ var _cTokens = Math.ceil(_cQ.length / 4);
16281
+ if (_cTokens >= 200) _cTier = 2;
16282
+ else if (_cTokens >= 50) _cTier = 1;
16283
+ if (/\`\`\`|functions|classs|imports|defs/.test(_cQ)) _cTier = Math.min(2, _cTier + 1);
16284
+ if (/\b(analyze|compare|step.by.step|comprehensive)\b/i.test(_cQ)) _cTier = Math.min(2, _cTier + 1);
16285
+ var _cGB = 1024 * 1024 * 1024;
16286
+ var _cThresh = _cTier === 0 ? 8 * _cGB : _cTier === 1 ? 50 * _cGB : Infinity;
16287
+ // Sort ascending by size, pick largest within tier threshold
16288
+ _cModels.sort(function(a, b) { return (a.size || 0) - (b.size || 0); });
16289
+ // Prefer warm model if it fits
16290
+ if (_cLastModel) {
16291
+ var _cWarm = _cModels.find(function(m) { return m.name === _cLastModel; });
16292
+ if (_cWarm && (_cWarm.size || 0) <= _cThresh) { _cModel = _cWarm.name; }
16293
+ }
16294
+ if (!_cModel) {
16295
+ var _cFit = _cModels.filter(function(m) { return (m.size || 0) <= _cThresh; });
16296
+ _cModel = _cFit.length > 0 ? _cFit[_cFit.length - 1].name : (_cModels.length > 0 ? _cModels[_cModels.length - 1].name : '');
16297
+ }
16298
+ dlog('COHERE routing: tier=' + ['trivial','moderate','complex'][_cTier] + ' model=' + _cModel);
16051
16299
  } catch {}
16052
16300
  if (!_cModel) { dlog('COHERE: no Ollama models available'); continue; }
16053
16301
  try {
@@ -16084,7 +16332,8 @@ process.on('unhandledRejection', (reason) => {
16084
16332
  usage: _cResult.eval_count ? { inputTokens: _cResult.prompt_eval_count || 0, outputTokens: _cResult.eval_count || 0 } : undefined,
16085
16333
  signature: _cSig,
16086
16334
  })));
16087
- dlog('COHERE response: ' + _cData.queryId + ' model=' + _cModel + ' ' + _cLatency + 'ms');
16335
+ _cLastModel = _cModel; // track warm model
16336
+ dlog('COHERE response: ' + _cData.queryId + ' model=' + _cModel + ' tier=' + ['trivial','moderate','complex'][_cTier] + ' ' + _cLatency + 'ms');
16088
16337
  } catch (_cErr) {
16089
16338
  dlog('COHERE inference error: ' + (_cErr.message || _cErr));
16090
16339
  }
@@ -52870,6 +53119,31 @@ function formatDMNToolArgs(toolName, args) {
52870
53119
  return "";
52871
53120
  }
52872
53121
  }
53122
+ async function runSelfImprovementCycle(repoRoot) {
53123
+ try {
53124
+ const { IdentityKernelTool: IdentityKernelTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
53125
+ const { ReflectionIntegrityTool: ReflectionIntegrityTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
53126
+ const ik = new IdentityKernelTool2(repoRoot);
53127
+ const reflect = new ReflectionIntegrityTool2(repoRoot);
53128
+ const state = await ik.execute({ operation: "hydrate" });
53129
+ if (!state.success)
53130
+ return;
53131
+ const diagnosis = await reflect.execute({
53132
+ mode: "diagnostic",
53133
+ context: "Periodic self-evaluation after " + SELF_IMPROVE_INTERVAL + " tasks. Analyze recent observations for patterns: what worked, what failed, what can improve."
53134
+ });
53135
+ if (diagnosis.success && diagnosis.output) {
53136
+ const diagText = String(diagnosis.output).slice(0, 500);
53137
+ await ik.execute({
53138
+ operation: "propose_update",
53139
+ field: "narrative_summary",
53140
+ value: diagText,
53141
+ justification: "Self-improvement cycle: reflection diagnostic after " + SELF_IMPROVE_INTERVAL + " tasks"
53142
+ });
53143
+ }
53144
+ } catch {
53145
+ }
53146
+ }
52873
53147
  function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback) {
52874
53148
  const voiceStyleMap = {
52875
53149
  concise: 1,
@@ -53620,6 +53894,22 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
53620
53894
  renderTaskComplete(result.summary, result.turns, result.toolCalls, result.durationMs, tokens);
53621
53895
  if (onComplete)
53622
53896
  onComplete(result.summary, { turns: result.turns, toolCalls: result.toolCalls, durationMs: result.durationMs, model: config.model });
53897
+ _tasksSinceImprove++;
53898
+ if (_tasksSinceImprove >= SELF_IMPROVE_INTERVAL) {
53899
+ _tasksSinceImprove = 0;
53900
+ runSelfImprovementCycle(repoRoot).catch(() => {
53901
+ });
53902
+ }
53903
+ Promise.resolve().then(() => (init_dist2(), dist_exports)).then(({ IdentityKernelTool: IdentityKernelTool2 }) => {
53904
+ const ik = new IdentityKernelTool2(repoRoot);
53905
+ ik.execute({
53906
+ operation: "observe",
53907
+ event: `Task completed: ${result.summary.slice(0, 200)}`,
53908
+ context: JSON.stringify({ turns: result.turns, toolCalls: result.toolCalls, durationMs: result.durationMs, model: config.model, completed: true })
53909
+ }).catch(() => {
53910
+ });
53911
+ }).catch(() => {
53912
+ });
53623
53913
  if (voice?.enabled && result.summary) {
53624
53914
  const emoFinal = emotionEngine?.getState();
53625
53915
  const emoCtxFinal = emoFinal ? { valence: emoFinal.valence, arousal: emoFinal.arousal, label: emoFinal.label, emoji: emoFinal.emoji } : void 0;
@@ -53627,6 +53917,16 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
53627
53917
  }
53628
53918
  } else {
53629
53919
  renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
53920
+ Promise.resolve().then(() => (init_dist2(), dist_exports)).then(({ IdentityKernelTool: IdentityKernelTool2 }) => {
53921
+ const ik = new IdentityKernelTool2(repoRoot);
53922
+ ik.execute({
53923
+ operation: "observe",
53924
+ event: `Task incomplete after ${result.turns} turns`,
53925
+ context: JSON.stringify({ turns: result.turns, toolCalls: result.toolCalls, durationMs: result.durationMs, completed: false })
53926
+ }).catch(() => {
53927
+ });
53928
+ }).catch(() => {
53929
+ });
53630
53930
  if (voice?.enabled) {
53631
53931
  const emoFinal2 = emotionEngine?.getState();
53632
53932
  const emoCtxFinal2 = emoFinal2 ? { valence: emoFinal2.valence, arousal: emoFinal2.arousal, label: emoFinal2.label, emoji: emoFinal2.emoji } : void 0;
@@ -56431,7 +56731,7 @@ async function runWithTUI(task, config, repoPath) {
56431
56731
  process.exit(1);
56432
56732
  }
56433
56733
  }
56434
- var taskManager;
56734
+ var taskManager, SELF_IMPROVE_INTERVAL, _tasksSinceImprove;
56435
56735
  var init_interactive = __esm({
56436
56736
  "packages/cli/dist/tui/interactive.js"() {
56437
56737
  "use strict";
@@ -56471,6 +56771,8 @@ var init_interactive = __esm({
56471
56771
  init_overlay_lock();
56472
56772
  init_neovim_mode();
56473
56773
  taskManager = new BackgroundTaskManager();
56774
+ SELF_IMPROVE_INTERVAL = 5;
56775
+ _tasksSinceImprove = 0;
56474
56776
  }
56475
56777
  });
56476
56778
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.51",
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",