open-agents-ai 0.138.80 → 0.138.81

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 +104 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5667,6 +5667,21 @@ async function handleCmd(cmd) {
5667
5667
  }
5668
5668
  }
5669
5669
  } catch {}
5670
+ // WO-DL4: IPFS pin the insight content for persistence + cross-node retrieval
5671
+ var _cpiCid = null;
5672
+ try {
5673
+ var _cpiHeliaReady = await _ensureHelia();
5674
+ if (_cpiHeliaReady && _heliaFs) {
5675
+ var _cpiBytes = new TextEncoder().encode(JSON.stringify({ insight: _cpiInsight, category: _cpiCategory, confidence: _cpiConfidence, tier: _cpiTier, agent: agentName, ts: Date.now() }));
5676
+ var _cpiCidObj = await _heliaFs.addBytes(_cpiBytes);
5677
+ for await (var _cpiPin of _heliaNode.pins.add(_cpiCidObj)) {}
5678
+ _cpiCid = _cpiCidObj.toString();
5679
+ dlog('IPFS pinned insight: ' + _cpiCid);
5680
+ }
5681
+ } catch (_cpiIpfsErr) {
5682
+ dlog('IPFS pin failed (graceful): ' + (_cpiIpfsErr.message || _cpiIpfsErr));
5683
+ }
5684
+
5670
5685
  var _cpiDelta = {
5671
5686
  type: 'cohere.learning',
5672
5687
  delta_id: 'insight-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 6),
@@ -5676,6 +5691,7 @@ async function handleCmd(cmd) {
5676
5691
  category: _cpiCategory,
5677
5692
  confidence: _cpiConfidence,
5678
5693
  model_tier: _cpiTier,
5694
+ cid: _cpiCid, // null if IPFS unavailable, CID string if pinned
5679
5695
  timestamp: Date.now(),
5680
5696
  };
5681
5697
  _natsConn.publish('nexus.cohere.learning', _natsCodec.encode(JSON.stringify(_cpiDelta)));
@@ -6971,6 +6987,31 @@ process.on('unhandledRejection', (reason) => {
6971
6987
  mkdirSync(_lStoreDir, { recursive: true });
6972
6988
  writeFileSync(_lStoreFile, JSON.stringify(_lStore, null, 2));
6973
6989
  dlog('COHERE learning ingested from ' + (_lData.source_agent || 'unknown') + ': ' + String(_lData.insight).slice(0, 60));
6990
+
6991
+ // WO-DL4: Cross-pin the CID locally if provided (content persistence)
6992
+ if (_lData.cid && _lData.cid.startsWith('bafy')) {
6993
+ try {
6994
+ var _lCidDir = join(nexusDir, 'ipfs', 'cid-registry');
6995
+ mkdirSync(_lCidDir, { recursive: true });
6996
+ var _lCidFile = join(_lCidDir, 'learning-cids.json');
6997
+ var _lCids = {};
6998
+ try { if (existsSync(_lCidFile)) _lCids = JSON.parse(readFileSync(_lCidFile, 'utf8')); } catch {}
6999
+ _lCids[_lData.delta_id] = { cid: _lData.cid, source: _lData.source_agent, pinned: false, timestamp: Date.now() };
7000
+ writeFileSync(_lCidFile, JSON.stringify(_lCids, null, 2));
7001
+ dlog('CID registered: ' + _lData.cid.slice(0, 20) + '... from ' + _lData.source_agent);
7002
+ // Attempt cross-pin if Helia is ready
7003
+ try {
7004
+ if (_heliaReady && _heliaNode) {
7005
+ var { CID: CIDClass } = await import('multiformats/cid');
7006
+ var _lCidObj = CIDClass.parse(_lData.cid);
7007
+ for await (var _lPin of _heliaNode.pins.add(_lCidObj)) {}
7008
+ _lCids[_lData.delta_id].pinned = true;
7009
+ writeFileSync(_lCidFile, JSON.stringify(_lCids, null, 2));
7010
+ dlog('Cross-pinned CID: ' + _lData.cid.slice(0, 20));
7011
+ }
7012
+ } catch {}
7013
+ } catch {}
7014
+ }
6974
7015
  } catch {}
6975
7016
  }
6976
7017
  })().catch(function(e) { dlog('COHERE learning listener error: ' + (e.message || e)); });
@@ -7032,6 +7073,69 @@ process.on('unhandledRejection', (reason) => {
7032
7073
  if (cohereActive) _publishCapacityAnnouncement();
7033
7074
  }, 60000);
7034
7075
 
7076
+ // \u2500\u2500 WO-DL3: Epoch sync \u2014 hash-based state comparison every 5 min \u2500\u2500
7077
+ // Each node publishes a lightweight fingerprint of its memory state.
7078
+ // If hashes differ between same-tier nodes, the lagging node can
7079
+ // request missing insights via nexus.cohere.learning.request.
7080
+ var _epochCounter = 0;
7081
+ function _publishEpochSync() {
7082
+ if (!cohereActive || !_natsConn || !_natsCodec) return;
7083
+ try {
7084
+ // Read local memory store for fingerprinting
7085
+ var _esStoreFile = join(nexusDir, '..', 'memory', 'metabolism', 'store.json');
7086
+ var _esStore = [];
7087
+ try { if (existsSync(_esStoreFile)) _esStore = JSON.parse(readFileSync(_esStoreFile, 'utf8')); } catch {}
7088
+
7089
+ // Compute top-10 memory IDs sorted by utility*confidence (deterministic)
7090
+ var _esFiltered = _esStore
7091
+ .filter(function(m) { return m.type !== 'quarantine' && m.scores && m.scores.confidence > 0.15; })
7092
+ .sort(function(a, b) { return (b.scores.utility * b.scores.confidence) - (a.scores.utility * a.scores.confidence); })
7093
+ .slice(0, 10);
7094
+ var _esTopIds = _esFiltered.map(function(m) { return m.id; }).sort().join(',');
7095
+
7096
+ // SHA-256 hash of top-10 IDs for compact comparison
7097
+ var _esHash = require('crypto').createHash('sha256').update(_esTopIds).digest('hex').slice(0, 16);
7098
+
7099
+ _epochCounter++;
7100
+ var _esAnnouncement = {
7101
+ type: 'cohere.epoch',
7102
+ peer: nexus.peerId,
7103
+ agentName: agentName,
7104
+ epoch: _epochCounter,
7105
+ memoryCount: _esStore.length,
7106
+ topHash: _esHash,
7107
+ insightsAvailable: _esFiltered.length,
7108
+ timestamp: Date.now(),
7109
+ };
7110
+ _natsConn.publish('nexus.cohere.learning.epoch', _natsCodec.encode(JSON.stringify(_esAnnouncement)));
7111
+ dlog('Epoch sync published: epoch=' + _epochCounter + ' memories=' + _esStore.length + ' hash=' + _esHash);
7112
+ } catch (e) {
7113
+ dlog('Epoch sync error: ' + (e.message || e));
7114
+ }
7115
+ }
7116
+
7117
+ // Epoch sync every 5 minutes
7118
+ setInterval(function() {
7119
+ if (cohereActive) _publishEpochSync();
7120
+ }, 300000);
7121
+ // Also publish on startup after a brief delay
7122
+ setTimeout(function() { if (cohereActive) _publishEpochSync(); }, 10000);
7123
+
7124
+ // Listen for epoch announcements from other nodes
7125
+ var _epochSub = _natsConn.subscribe('nexus.cohere.learning.epoch');
7126
+ (async function() {
7127
+ for await (var _eMsg of _epochSub) {
7128
+ try {
7129
+ var _eData = JSON.parse(_natsCodec.decode(_eMsg.data));
7130
+ if (!_eData.peer || _eData.peer === nexus.peerId) continue;
7131
+ // Log peer epoch state for dashboard visibility
7132
+ dlog('Epoch from ' + (_eData.agentName || 'peer') + ': epoch=' + _eData.epoch + ' memories=' + _eData.memoryCount + ' hash=' + _eData.topHash);
7133
+ // Future: if our hash differs and they have more insights, request sync
7134
+ } catch {}
7135
+ }
7136
+ })().catch(function(e) { dlog('Epoch listener error: ' + (e.message || e)); });
7137
+ dlog('Epoch sync listener active on nexus.cohere.learning.epoch');
7138
+
7035
7139
  // Lazy-init IPFS in background (non-blocking)
7036
7140
  _ensureHelia().catch(function() {});
7037
7141
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.80",
3
+ "version": "0.138.81",
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",