open-agents-ai 0.138.79 → 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.
- package/dist/index.js +160 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5653,6 +5653,35 @@ async function handleCmd(cmd) {
|
|
|
5653
5653
|
var _cpiConfidence = parseFloat(args.confidence || '0.7');
|
|
5654
5654
|
if (!_cpiInsight) { writeResp(id, { ok: false, output: 'insight text required' }); break; }
|
|
5655
5655
|
try {
|
|
5656
|
+
// Detect local model tier from warm model
|
|
5657
|
+
var _cpiTier = 'unknown';
|
|
5658
|
+
try {
|
|
5659
|
+
var _cpiOllamaUrl = process.env.OLLAMA_HOST || 'http://localhost:11434';
|
|
5660
|
+
if (_cLastModel) {
|
|
5661
|
+
var _cpiTagsResp = await fetch(_cpiOllamaUrl + '/api/tags');
|
|
5662
|
+
var _cpiTags = await _cpiTagsResp.json();
|
|
5663
|
+
var _cpiModel = (_cpiTags.models || []).find(function(m) { return m.name === _cLastModel; });
|
|
5664
|
+
if (_cpiModel) {
|
|
5665
|
+
var _cpiSizeGB = (_cpiModel.size || 0) / (1024*1024*1024);
|
|
5666
|
+
_cpiTier = _cpiSizeGB >= 20 ? 'large' : _cpiSizeGB >= 5 ? 'medium' : 'small';
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
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
|
+
|
|
5656
5685
|
var _cpiDelta = {
|
|
5657
5686
|
type: 'cohere.learning',
|
|
5658
5687
|
delta_id: 'insight-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 6),
|
|
@@ -5661,7 +5690,8 @@ async function handleCmd(cmd) {
|
|
|
5661
5690
|
insight: String(_cpiInsight).slice(0, 500),
|
|
5662
5691
|
category: _cpiCategory,
|
|
5663
5692
|
confidence: _cpiConfidence,
|
|
5664
|
-
model_tier:
|
|
5693
|
+
model_tier: _cpiTier,
|
|
5694
|
+
cid: _cpiCid, // null if IPFS unavailable, CID string if pinned
|
|
5665
5695
|
timestamp: Date.now(),
|
|
5666
5696
|
};
|
|
5667
5697
|
_natsConn.publish('nexus.cohere.learning', _natsCodec.encode(JSON.stringify(_cpiDelta)));
|
|
@@ -6887,6 +6917,47 @@ process.on('unhandledRejection', (reason) => {
|
|
|
6887
6917
|
if (!_lData.insight || !_lData.source_peer) continue;
|
|
6888
6918
|
// Skip our own insights
|
|
6889
6919
|
if (_lData.source_peer === nexus.peerId) continue;
|
|
6920
|
+
|
|
6921
|
+
// WO-DL2: Model-tier-aware ingestion filtering
|
|
6922
|
+
// Determine local model tier from warm model size
|
|
6923
|
+
var _lLocalTier = 'unknown';
|
|
6924
|
+
try {
|
|
6925
|
+
var _lOllamaUrl = process.env.OLLAMA_HOST || 'http://localhost:11434';
|
|
6926
|
+
if (_cLastModel) {
|
|
6927
|
+
var _lTagsResp = await fetch(_lOllamaUrl + '/api/tags');
|
|
6928
|
+
var _lTags = await _lTagsResp.json();
|
|
6929
|
+
var _lModel = (_lTags.models || []).find(function(m) { return m.name === _cLastModel; });
|
|
6930
|
+
if (_lModel) {
|
|
6931
|
+
var _lSizeGB = (_lModel.size || 0) / (1024*1024*1024);
|
|
6932
|
+
_lLocalTier = _lSizeGB >= 20 ? 'large' : _lSizeGB >= 5 ? 'medium' : 'small';
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
} catch {}
|
|
6936
|
+
|
|
6937
|
+
var _lSourceTier = _lData.model_tier || 'unknown';
|
|
6938
|
+
var _lCategory = _lData.category || 'strategy';
|
|
6939
|
+
var _lConfidence = _lData.confidence || 0.5;
|
|
6940
|
+
|
|
6941
|
+
// Tier filtering rules:
|
|
6942
|
+
// - Same or lower tier \u2192 always ingest
|
|
6943
|
+
// - Higher tier \u2192 only if confidence > 0.8 AND category is recovery (model-agnostic)
|
|
6944
|
+
// - Never ingest complex strategies from much larger models to tiny models
|
|
6945
|
+
var _lTierOrder = { 'small': 0, 'medium': 1, 'large': 2, 'unknown': 1 };
|
|
6946
|
+
var _lLocalLevel = _lTierOrder[_lLocalTier] || 1;
|
|
6947
|
+
var _lSourceLevel = _lTierOrder[_lSourceTier] || 1;
|
|
6948
|
+
|
|
6949
|
+
if (_lSourceLevel > _lLocalLevel) {
|
|
6950
|
+
// Insight from a LARGER model \u2014 apply strict filtering
|
|
6951
|
+
if (_lConfidence < 0.8) {
|
|
6952
|
+
dlog('COHERE learning SKIPPED (low confidence from higher tier): ' + _lCategory + ' conf=' + _lConfidence);
|
|
6953
|
+
continue;
|
|
6954
|
+
}
|
|
6955
|
+
if (_lCategory !== 'recovery' && _lCategory !== 'debug_heuristic') {
|
|
6956
|
+
dlog('COHERE learning SKIPPED (non-recovery from higher tier): ' + _lCategory);
|
|
6957
|
+
continue;
|
|
6958
|
+
}
|
|
6959
|
+
}
|
|
6960
|
+
|
|
6890
6961
|
// Ingest: write to local metabolism store
|
|
6891
6962
|
var _lStoreDir = join(nexusDir, '..', 'memory', 'metabolism');
|
|
6892
6963
|
var _lStoreFile = join(_lStoreDir, 'store.json');
|
|
@@ -6916,6 +6987,31 @@ process.on('unhandledRejection', (reason) => {
|
|
|
6916
6987
|
mkdirSync(_lStoreDir, { recursive: true });
|
|
6917
6988
|
writeFileSync(_lStoreFile, JSON.stringify(_lStore, null, 2));
|
|
6918
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
|
+
}
|
|
6919
7015
|
} catch {}
|
|
6920
7016
|
}
|
|
6921
7017
|
})().catch(function(e) { dlog('COHERE learning listener error: ' + (e.message || e)); });
|
|
@@ -6977,6 +7073,69 @@ process.on('unhandledRejection', (reason) => {
|
|
|
6977
7073
|
if (cohereActive) _publishCapacityAnnouncement();
|
|
6978
7074
|
}, 60000);
|
|
6979
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
|
+
|
|
6980
7139
|
// Lazy-init IPFS in background (non-blocking)
|
|
6981
7140
|
_ensureHelia().catch(function() {});
|
|
6982
7141
|
}
|
package/package.json
CHANGED