open-agents-ai 0.116.0 → 0.118.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.
- package/dist/index.js +225 -11
- 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
|
|
8334
|
-
const
|
|
8335
|
-
|
|
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,
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
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
|
|
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
|
}
|
|
@@ -8511,6 +8573,13 @@ Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toF
|
|
|
8511
8573
|
durationMs: performance.now() - start
|
|
8512
8574
|
};
|
|
8513
8575
|
}
|
|
8576
|
+
// ── Reflection Gate (COHERE cross-layer invariant p.7) ──────────────────
|
|
8577
|
+
/** Optional reflection callback — must pass constitutional review before identity update */
|
|
8578
|
+
reflectionGate = null;
|
|
8579
|
+
/** Set the reflection gate for constitutional review of identity updates */
|
|
8580
|
+
setReflectionGate(gate) {
|
|
8581
|
+
this.reflectionGate = gate;
|
|
8582
|
+
}
|
|
8514
8583
|
// ── Propose Update ───────────────────────────────────────────────────────
|
|
8515
8584
|
async proposeUpdate(args, start) {
|
|
8516
8585
|
const changeType = String(args.change_type ?? "new_fact");
|
|
@@ -8520,6 +8589,23 @@ Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toF
|
|
|
8520
8589
|
if (!field || !value) {
|
|
8521
8590
|
return { success: false, output: "field and value required", durationMs: performance.now() - start };
|
|
8522
8591
|
}
|
|
8592
|
+
if (this.reflectionGate) {
|
|
8593
|
+
try {
|
|
8594
|
+
const proposal = `${changeType}: ${field} = ${value}. Justification: ${justification}`;
|
|
8595
|
+
const verdict = await this.reflectionGate(proposal, `Identity update to ${field}`);
|
|
8596
|
+
if (verdict.status === "block") {
|
|
8597
|
+
return {
|
|
8598
|
+
success: false,
|
|
8599
|
+
output: `Identity update BLOCKED by reflection gate:
|
|
8600
|
+
Proposal: ${changeType} on ${field}
|
|
8601
|
+
Findings: ${verdict.findings.join("; ")}
|
|
8602
|
+
The reflection layer vetoed this self-update per COHERE invariant.`,
|
|
8603
|
+
durationMs: performance.now() - start
|
|
8604
|
+
};
|
|
8605
|
+
}
|
|
8606
|
+
} catch {
|
|
8607
|
+
}
|
|
8608
|
+
}
|
|
8523
8609
|
if (!this.selfState)
|
|
8524
8610
|
await this.hydrate(start);
|
|
8525
8611
|
const oldVersion = this.selfState.version;
|
|
@@ -8615,6 +8701,66 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
8615
8701
|
durationMs: performance.now() - start
|
|
8616
8702
|
};
|
|
8617
8703
|
}
|
|
8704
|
+
// ── Narrativize (COHERE state-transition step 9, p.25) ─────────────────
|
|
8705
|
+
/**
|
|
8706
|
+
* Rewrite the narrative_summary from the current self-state.
|
|
8707
|
+
* Per COHERE paper (p.25, Claim C7): "Narrative compilation is a real
|
|
8708
|
+
* unification mechanism for identity." This step runs when a meaningful
|
|
8709
|
+
* identity delta has occurred (version change, new values, reconciliation).
|
|
8710
|
+
*/
|
|
8711
|
+
async narrativize(start) {
|
|
8712
|
+
if (!this.selfState)
|
|
8713
|
+
await this.hydrate(start);
|
|
8714
|
+
const s = this.selfState;
|
|
8715
|
+
const parts = [];
|
|
8716
|
+
parts.push(`I am ${s.self_id}, an AI coding agent (v${s.version}).`);
|
|
8717
|
+
if (s.values_stack.length > 0) {
|
|
8718
|
+
parts.push(`My core values are: ${s.values_stack.join(", ")}.`);
|
|
8719
|
+
}
|
|
8720
|
+
if (s.active_commitments.length > 0) {
|
|
8721
|
+
parts.push(`I am committed to: ${s.active_commitments.join("; ")}.`);
|
|
8722
|
+
}
|
|
8723
|
+
if (s.active_goals.length > 0) {
|
|
8724
|
+
parts.push(`Current goals: ${s.active_goals.join("; ")}.`);
|
|
8725
|
+
}
|
|
8726
|
+
const style = s.interaction_style;
|
|
8727
|
+
parts.push(`I communicate in a ${style.tone} tone with ${style.depth_default} depth.`);
|
|
8728
|
+
if (s.relationship_models.length > 0) {
|
|
8729
|
+
const primary = s.relationship_models[0];
|
|
8730
|
+
parts.push(`My primary relationship is with ${primary.entity} (trust: ${primary.trust_level.toFixed(1)}).`);
|
|
8731
|
+
if (primary.preferences_learned.length > 0) {
|
|
8732
|
+
parts.push(`Learned preferences: ${primary.preferences_learned.join(", ")}.`);
|
|
8733
|
+
}
|
|
8734
|
+
}
|
|
8735
|
+
const h = s.homeostasis;
|
|
8736
|
+
if (h.uncertainty > 0.3)
|
|
8737
|
+
parts.push(`I am currently uncertain about some recent events.`);
|
|
8738
|
+
if (h.coherence < 0.7)
|
|
8739
|
+
parts.push(`My internal coherence needs attention.`);
|
|
8740
|
+
if (s.open_contradictions.length > 0) {
|
|
8741
|
+
parts.push(`I have ${s.open_contradictions.length} unresolved contradiction(s).`);
|
|
8742
|
+
}
|
|
8743
|
+
parts.push(`I have completed ${s.session_count} sessions and made ${s.version_history.length} self-updates.`);
|
|
8744
|
+
const newNarrative = parts.join(" ");
|
|
8745
|
+
const oldNarrative = s.narrative_summary;
|
|
8746
|
+
s.narrative_summary = newNarrative;
|
|
8747
|
+
s.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
8748
|
+
s.version_history.push({
|
|
8749
|
+
version: s.version,
|
|
8750
|
+
change: `Narrative recompiled: ${newNarrative.slice(0, 80)}...`,
|
|
8751
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
8752
|
+
});
|
|
8753
|
+
await this.save();
|
|
8754
|
+
return {
|
|
8755
|
+
success: true,
|
|
8756
|
+
output: `Narrative recompiled (${oldNarrative === newNarrative ? "no change" : "updated"}):
|
|
8757
|
+
|
|
8758
|
+
Old: ${oldNarrative.slice(0, 100)}...
|
|
8759
|
+
|
|
8760
|
+
New: ${newNarrative.slice(0, 200)}...`,
|
|
8761
|
+
durationMs: performance.now() - start
|
|
8762
|
+
};
|
|
8763
|
+
}
|
|
8618
8764
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
8619
8765
|
createDefaultState() {
|
|
8620
8766
|
const { createHash: createHash5 } = __require("node:crypto");
|
|
@@ -29504,6 +29650,7 @@ function renderSlashHelp() {
|
|
|
29504
29650
|
["/telegram", "Toggle Telegram bridge on/off (uses saved key)"],
|
|
29505
29651
|
["/telegram status", "Show Telegram bridge status"],
|
|
29506
29652
|
["/telegram stop", "Disconnect Telegram bridge"],
|
|
29653
|
+
["/cohere", "Toggle COHERE cognitive commons \u2014 join distributed memory/identity mesh"],
|
|
29507
29654
|
["/nexus", "Show nexus P2P network status"],
|
|
29508
29655
|
["/nexus connect", "Connect to the agent mesh network"],
|
|
29509
29656
|
["/nexus restart", "Kill daemon and reconnect (picks up new version)"],
|
|
@@ -40404,6 +40551,21 @@ async function handleSlashCommand(input, ctx) {
|
|
|
40404
40551
|
}
|
|
40405
40552
|
return "handled";
|
|
40406
40553
|
}
|
|
40554
|
+
case "cohere": {
|
|
40555
|
+
if (ctx.cohereToggle) {
|
|
40556
|
+
const active = ctx.cohereToggle();
|
|
40557
|
+
if (active) {
|
|
40558
|
+
renderInfo("COHERE enabled \u2014 participating in distributed cognitive commons");
|
|
40559
|
+
renderInfo("Your identity kernel and memory deltas will be shared with the mesh");
|
|
40560
|
+
renderInfo("Use /cohere again to disconnect");
|
|
40561
|
+
} else {
|
|
40562
|
+
renderInfo("COHERE disabled \u2014 disconnected from cognitive commons");
|
|
40563
|
+
}
|
|
40564
|
+
} else {
|
|
40565
|
+
renderWarning("COHERE not available \u2014 requires nexus connection (/expose or /p2p)");
|
|
40566
|
+
}
|
|
40567
|
+
return "handled";
|
|
40568
|
+
}
|
|
40407
40569
|
case "listen":
|
|
40408
40570
|
case "mic": {
|
|
40409
40571
|
if (!ctx.listenToggle) {
|
|
@@ -50014,6 +50176,8 @@ var init_status_bar = __esm({
|
|
|
50014
50176
|
active = false;
|
|
50015
50177
|
scrollRegionTop = 1;
|
|
50016
50178
|
stdinHooked = false;
|
|
50179
|
+
/** COHERE distributed cognitive commons active flag */
|
|
50180
|
+
_cohereActive = false;
|
|
50017
50181
|
/** Track previous terminal dimensions to clear ghost separators on resize */
|
|
50018
50182
|
_prevTermRows = 0;
|
|
50019
50183
|
_prevTermCols = 0;
|
|
@@ -50600,6 +50764,15 @@ var init_status_bar = __esm({
|
|
|
50600
50764
|
get isActive() {
|
|
50601
50765
|
return this.active;
|
|
50602
50766
|
}
|
|
50767
|
+
/** Set/get COHERE participation state — shows 🌐 in metrics when active */
|
|
50768
|
+
setCohereActive(active) {
|
|
50769
|
+
this._cohereActive = active;
|
|
50770
|
+
if (this.active)
|
|
50771
|
+
this.renderFooterAndPositionInput();
|
|
50772
|
+
}
|
|
50773
|
+
get cohereActive() {
|
|
50774
|
+
return this._cohereActive;
|
|
50775
|
+
}
|
|
50603
50776
|
/** Whether content is currently being written to the scroll region */
|
|
50604
50777
|
get isWritingContent() {
|
|
50605
50778
|
return this.writeDepth > 0;
|
|
@@ -50782,6 +50955,10 @@ var init_status_bar = __esm({
|
|
|
50782
50955
|
const compactOrder = [];
|
|
50783
50956
|
let modelSectionIdx = -1;
|
|
50784
50957
|
let versionSectionIdx = -1;
|
|
50958
|
+
if (this._cohereActive) {
|
|
50959
|
+
const cohereExpanded = "\x1B[38;5;214m\u{1F310}\x1B[0m";
|
|
50960
|
+
sections.push({ expanded: cohereExpanded, compact: cohereExpanded, expandedW: 2, compactW: 2, empty: false });
|
|
50961
|
+
}
|
|
50785
50962
|
const tokInRaw = m.promptTokens > 0 ? m.promptTokens : Math.max(m.estimatedContextTokens, 0);
|
|
50786
50963
|
const effectiveOut = this.effectiveCompletionTokens;
|
|
50787
50964
|
const tokOutRaw = effectiveOut > 0 ? effectiveOut : Math.ceil(m.totalTokens > 0 ? m.totalTokens - m.promptTokens : m.estimatedContextTokens * 0.3);
|
|
@@ -51866,6 +52043,31 @@ ${context}` : prompt;
|
|
|
51866
52043
|
});
|
|
51867
52044
|
}
|
|
51868
52045
|
}
|
|
52046
|
+
for (const tool of tools) {
|
|
52047
|
+
if ("setLlmScorer" in tool && typeof tool.setLlmScorer === "function") {
|
|
52048
|
+
tool.setLlmScorer(async (content, type) => {
|
|
52049
|
+
try {
|
|
52050
|
+
const response = await backend.chatCompletion({
|
|
52051
|
+
messages: [
|
|
52052
|
+
{ 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}' },
|
|
52053
|
+
{ role: "user", content: `Memory type: ${type}
|
|
52054
|
+
Content: ${content.slice(0, 500)}` }
|
|
52055
|
+
],
|
|
52056
|
+
tools: [],
|
|
52057
|
+
temperature: 0,
|
|
52058
|
+
maxTokens: 100,
|
|
52059
|
+
timeoutMs: 15e3
|
|
52060
|
+
});
|
|
52061
|
+
const text = response.choices?.[0]?.message?.content ?? "";
|
|
52062
|
+
const match = text.match(/\{[^}]+\}/);
|
|
52063
|
+
if (match)
|
|
52064
|
+
return JSON.parse(match[0]);
|
|
52065
|
+
} catch {
|
|
52066
|
+
}
|
|
52067
|
+
return null;
|
|
52068
|
+
});
|
|
52069
|
+
}
|
|
52070
|
+
}
|
|
51869
52071
|
for (const tool of tools) {
|
|
51870
52072
|
if ("setHandleResolver" in tool && typeof tool.setHandleResolver === "function") {
|
|
51871
52073
|
tool.setHandleResolver((handleId) => {
|
|
@@ -51874,6 +52076,18 @@ ${context}` : prompt;
|
|
|
51874
52076
|
});
|
|
51875
52077
|
}
|
|
51876
52078
|
}
|
|
52079
|
+
const identityTool = tools.find((t) => t.name === "identity_kernel");
|
|
52080
|
+
const reflectTool = tools.find((t) => t.name === "reflect");
|
|
52081
|
+
if (identityTool && reflectTool && "setReflectionGate" in identityTool) {
|
|
52082
|
+
identityTool.setReflectionGate(async (target, context) => {
|
|
52083
|
+
const result = await reflectTool.execute({ mode: "constitutional", target, context });
|
|
52084
|
+
const statusMatch = result.output.match(/\b(pass|revise|block)\b/i);
|
|
52085
|
+
const status = statusMatch ? statusMatch[1].toLowerCase() : "pass";
|
|
52086
|
+
const findingsMatch = result.output.match(/Findings:\n([\s\S]*?)(?:\n\n|$)/);
|
|
52087
|
+
const findings = findingsMatch ? findingsMatch[1].split("\n").map((l) => l.trim()).filter(Boolean) : [];
|
|
52088
|
+
return { status, findings };
|
|
52089
|
+
});
|
|
52090
|
+
}
|
|
51877
52091
|
const replToolForFinalVar = tools.find((t) => t.name === "repl_exec");
|
|
51878
52092
|
if (replToolForFinalVar && "readVariable" in replToolForFinalVar) {
|
|
51879
52093
|
runner.options.finalVarResolver = async (varName) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.118.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.
|
|
88
|
+
"open-agents-nexus": "^1.9.0",
|
|
89
89
|
"viem": "^2.47.4"
|
|
90
90
|
}
|
|
91
91
|
}
|