open-agents-ai 0.116.0 → 0.117.0

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 +158 -11
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -8327,18 +8327,78 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
8327
8327
  }
8328
8328
  return false;
8329
8329
  }
8330
- // ── Scoring ──────────────────────────────────────────────────────────────
8330
+ // ── Scoring (A-MAC inspired, COHERE Memory Metabolism §4) ───────────────
8331
+ // Per COHERE paper: admission scoring covers novelty, utility, confidence,
8332
+ // and identity_relevance. Enhanced heuristics cover 12 content signals.
8333
+ // Optional LLM-assisted scoring available via setLlmScorer().
8334
+ /** Optional LLM-based scorer for production-quality admission decisions */
8335
+ llmScorer = null;
8336
+ /** Set an LLM-based scorer for production-quality memory admission */
8337
+ setLlmScorer(scorer) {
8338
+ this.llmScorer = scorer;
8339
+ }
8331
8340
  scoreMemory(content, type, source) {
8332
8341
  const words = content.split(/\s+/).length;
8333
- const hasCode = /```|def |function |import |require/.test(content);
8334
- const hasError = /error|fail|bug|fix/i.test(content);
8335
- const hasPattern = /pattern|strategy|approach|lesson|tip/i.test(content);
8342
+ const sentences = content.split(/[.!?]+/).filter((s) => s.trim()).length;
8343
+ const lower = content.toLowerCase();
8344
+ let novelty = 0.3;
8345
+ novelty += Math.min(0.3, words / 150);
8346
+ if (/\b[A-Z][a-z]+(?:\s[A-Z][a-z]+)+/.test(content))
8347
+ novelty += 0.1;
8348
+ if (/\d+\.\d+|\b\d{4,}\b/.test(content))
8349
+ novelty += 0.1;
8350
+ if (/\b(?:api|endpoint|schema|protocol|algorithm|architecture)\b/i.test(lower))
8351
+ novelty += 0.1;
8352
+ if (/\d{4}-\d{2}-\d{2}|today|yesterday|just now/i.test(lower))
8353
+ novelty += 0.1;
8354
+ let utility = 0.3;
8355
+ if (/```|def |function |import |require|class |interface |export /.test(content))
8356
+ utility += 0.25;
8357
+ if (/pattern|strategy|approach|lesson|tip|best practice|rule|principle/i.test(lower))
8358
+ utility += 0.2;
8359
+ if (/error|fail|bug|fix|solution|workaround|resolved/i.test(lower))
8360
+ utility += 0.15;
8361
+ if (/step\s*\d|first.*then|1\.|2\.|procedure|recipe|workflow/i.test(lower))
8362
+ utility += 0.15;
8363
+ if (/https?:\/\/|\/[a-z]+\/[a-z]+|npm |pip |git /i.test(lower))
8364
+ utility += 0.1;
8365
+ let confidence = 0.5;
8366
+ if (source === "user")
8367
+ confidence += 0.3;
8368
+ else if (source === "trajectory-consolidation")
8369
+ confidence += 0.15;
8370
+ else if (source === "reflection")
8371
+ confidence += 0.1;
8372
+ else if (source === "llm-query")
8373
+ confidence -= 0.1;
8374
+ if (/maybe|probably|might|possibly|I think|not sure|unclear/i.test(lower))
8375
+ confidence -= 0.15;
8376
+ if (/always|never|must|confirmed|verified|tested|proven/i.test(lower))
8377
+ confidence += 0.1;
8378
+ if (sentences >= 3)
8379
+ confidence += 0.05;
8380
+ let identityRelevance = 0.2;
8381
+ if (type === "normative")
8382
+ identityRelevance += 0.5;
8383
+ else if (type === "procedural")
8384
+ identityRelevance += 0.3;
8385
+ else if (type === "semantic")
8386
+ identityRelevance += 0.2;
8387
+ else if (type === "episodic")
8388
+ identityRelevance += 0.1;
8389
+ else if (type === "working")
8390
+ identityRelevance = 0.05;
8391
+ if (/\b(?:I|my|me|mine|myself|we|our)\b/i.test(content))
8392
+ identityRelevance += 0.1;
8393
+ if (/value|prefer|commit|important|priority|principle|belief/i.test(lower))
8394
+ identityRelevance += 0.15;
8395
+ if (/user|client|customer|team|collaborat/i.test(lower))
8396
+ identityRelevance += 0.1;
8336
8397
  return {
8337
- novelty: Math.min(1, words / 100),
8338
- // longer = likely more novel
8339
- utility: hasCode ? 0.8 : hasPattern ? 0.7 : hasError ? 0.6 : 0.4,
8340
- confidence: source === "trajectory-consolidation" ? 0.7 : source === "user" ? 0.9 : 0.5,
8341
- identityRelevance: type === "normative" ? 0.9 : type === "procedural" ? 0.6 : type === "semantic" ? 0.5 : 0.3
8398
+ novelty: Math.max(0, Math.min(1, novelty)),
8399
+ utility: Math.max(0, Math.min(1, utility)),
8400
+ confidence: Math.max(0, Math.min(1, confidence)),
8401
+ identityRelevance: Math.max(0, Math.min(1, identityRelevance))
8342
8402
  };
8343
8403
  }
8344
8404
  // ── Store I/O ────────────────────────────────────────────────────────────
@@ -8373,8 +8433,8 @@ var init_identity_kernel = __esm({
8373
8433
  properties: {
8374
8434
  op: {
8375
8435
  type: "string",
8376
- enum: ["hydrate", "observe", "propose_update", "publish_snapshot", "reconcile"],
8377
- description: "Operation to perform"
8436
+ enum: ["hydrate", "observe", "propose_update", "publish_snapshot", "reconcile", "narrativize"],
8437
+ 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)"
8378
8438
  },
8379
8439
  event: {
8380
8440
  type: "string",
@@ -8450,6 +8510,8 @@ var init_identity_kernel = __esm({
8450
8510
  return this.publishSnapshot(start);
8451
8511
  case "reconcile":
8452
8512
  return await this.reconcile(start);
8513
+ case "narrativize":
8514
+ return await this.narrativize(start);
8453
8515
  default:
8454
8516
  return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8455
8517
  }
@@ -8615,6 +8677,66 @@ Justification: ${justification || "(none provided)"}`,
8615
8677
  durationMs: performance.now() - start
8616
8678
  };
8617
8679
  }
8680
+ // ── Narrativize (COHERE state-transition step 9, p.25) ─────────────────
8681
+ /**
8682
+ * Rewrite the narrative_summary from the current self-state.
8683
+ * Per COHERE paper (p.25, Claim C7): "Narrative compilation is a real
8684
+ * unification mechanism for identity." This step runs when a meaningful
8685
+ * identity delta has occurred (version change, new values, reconciliation).
8686
+ */
8687
+ async narrativize(start) {
8688
+ if (!this.selfState)
8689
+ await this.hydrate(start);
8690
+ const s = this.selfState;
8691
+ const parts = [];
8692
+ parts.push(`I am ${s.self_id}, an AI coding agent (v${s.version}).`);
8693
+ if (s.values_stack.length > 0) {
8694
+ parts.push(`My core values are: ${s.values_stack.join(", ")}.`);
8695
+ }
8696
+ if (s.active_commitments.length > 0) {
8697
+ parts.push(`I am committed to: ${s.active_commitments.join("; ")}.`);
8698
+ }
8699
+ if (s.active_goals.length > 0) {
8700
+ parts.push(`Current goals: ${s.active_goals.join("; ")}.`);
8701
+ }
8702
+ const style = s.interaction_style;
8703
+ parts.push(`I communicate in a ${style.tone} tone with ${style.depth_default} depth.`);
8704
+ if (s.relationship_models.length > 0) {
8705
+ const primary = s.relationship_models[0];
8706
+ parts.push(`My primary relationship is with ${primary.entity} (trust: ${primary.trust_level.toFixed(1)}).`);
8707
+ if (primary.preferences_learned.length > 0) {
8708
+ parts.push(`Learned preferences: ${primary.preferences_learned.join(", ")}.`);
8709
+ }
8710
+ }
8711
+ const h = s.homeostasis;
8712
+ if (h.uncertainty > 0.3)
8713
+ parts.push(`I am currently uncertain about some recent events.`);
8714
+ if (h.coherence < 0.7)
8715
+ parts.push(`My internal coherence needs attention.`);
8716
+ if (s.open_contradictions.length > 0) {
8717
+ parts.push(`I have ${s.open_contradictions.length} unresolved contradiction(s).`);
8718
+ }
8719
+ parts.push(`I have completed ${s.session_count} sessions and made ${s.version_history.length} self-updates.`);
8720
+ const newNarrative = parts.join(" ");
8721
+ const oldNarrative = s.narrative_summary;
8722
+ s.narrative_summary = newNarrative;
8723
+ s.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8724
+ s.version_history.push({
8725
+ version: s.version,
8726
+ change: `Narrative recompiled: ${newNarrative.slice(0, 80)}...`,
8727
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8728
+ });
8729
+ await this.save();
8730
+ return {
8731
+ success: true,
8732
+ output: `Narrative recompiled (${oldNarrative === newNarrative ? "no change" : "updated"}):
8733
+
8734
+ Old: ${oldNarrative.slice(0, 100)}...
8735
+
8736
+ New: ${newNarrative.slice(0, 200)}...`,
8737
+ durationMs: performance.now() - start
8738
+ };
8739
+ }
8618
8740
  // ── Helpers ──────────────────────────────────────────────────────────────
8619
8741
  createDefaultState() {
8620
8742
  const { createHash: createHash5 } = __require("node:crypto");
@@ -51866,6 +51988,31 @@ ${context}` : prompt;
51866
51988
  });
51867
51989
  }
51868
51990
  }
51991
+ for (const tool of tools) {
51992
+ if ("setLlmScorer" in tool && typeof tool.setLlmScorer === "function") {
51993
+ tool.setLlmScorer(async (content, type) => {
51994
+ try {
51995
+ const response = await backend.chatCompletion({
51996
+ messages: [
51997
+ { role: "system", content: 'Score this memory candidate on 4 dimensions (0.0-1.0 each). Reply ONLY with JSON: {"novelty":N,"utility":N,"confidence":N,"identityRelevance":N}' },
51998
+ { role: "user", content: `Memory type: ${type}
51999
+ Content: ${content.slice(0, 500)}` }
52000
+ ],
52001
+ tools: [],
52002
+ temperature: 0,
52003
+ maxTokens: 100,
52004
+ timeoutMs: 15e3
52005
+ });
52006
+ const text = response.choices?.[0]?.message?.content ?? "";
52007
+ const match = text.match(/\{[^}]+\}/);
52008
+ if (match)
52009
+ return JSON.parse(match[0]);
52010
+ } catch {
52011
+ }
52012
+ return null;
52013
+ });
52014
+ }
52015
+ }
51869
52016
  for (const tool of tools) {
51870
52017
  if ("setHandleResolver" in tool && typeof tool.setHandleResolver === "function") {
51871
52018
  tool.setHandleResolver((handleId) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.116.0",
3
+ "version": "0.117.0",
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",
@@ -85,7 +85,7 @@
85
85
  "moondream": "^0.2.0",
86
86
  "neovim": "^5.3.0",
87
87
  "node-pty": "^1.0.0",
88
- "open-agents-nexus": "^1.8.0",
88
+ "open-agents-nexus": "^1.8.1",
89
89
  "viem": "^2.47.4"
90
90
  }
91
91
  }