open-agents-ai 0.138.47 → 0.138.49
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 +156 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14273,6 +14273,8 @@ const nexus = new NexusClient(nexusOpts);
|
|
|
14273
14273
|
const rooms = new Map();
|
|
14274
14274
|
let connected = false;
|
|
14275
14275
|
const blockedPeers = [];
|
|
14276
|
+
let cohereActive = false;
|
|
14277
|
+
const cohereDedup = new Map(); // queryId -> timestamp (60s TTL dedup)
|
|
14276
14278
|
|
|
14277
14279
|
// NATS invoke relay \u2014 for cross-NAT fallback when direct libp2p dial fails.
|
|
14278
14280
|
// Both peers connect to wss://demo.nats.io:8443, so NATS request/reply bridges the gap.
|
|
@@ -14997,6 +14999,20 @@ async function handleCmd(cmd) {
|
|
|
14997
14999
|
break;
|
|
14998
15000
|
}
|
|
14999
15001
|
|
|
15002
|
+
// \u2500\u2500 COHERE distributed inference toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
15003
|
+
case 'cohere_enable': {
|
|
15004
|
+
cohereActive = true;
|
|
15005
|
+
dlog('COHERE query handler enabled \u2014 listening on nexus.cohere.query');
|
|
15006
|
+
writeResp(id, { ok: true, output: 'COHERE inference handler enabled' });
|
|
15007
|
+
break;
|
|
15008
|
+
}
|
|
15009
|
+
case 'cohere_disable': {
|
|
15010
|
+
cohereActive = false;
|
|
15011
|
+
dlog('COHERE query handler disabled');
|
|
15012
|
+
writeResp(id, { ok: true, output: 'COHERE inference handler disabled' });
|
|
15013
|
+
break;
|
|
15014
|
+
}
|
|
15015
|
+
|
|
15000
15016
|
// \u2500\u2500 Metered Inference Exposure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
15001
15017
|
case 'expose': {
|
|
15002
15018
|
// Clear old inference capabilities before registering new ones
|
|
@@ -16000,6 +16016,86 @@ process.on('unhandledRejection', (reason) => {
|
|
|
16000
16016
|
dlog('NATS invoke relay setup failed: ' + (_nSetupErr.message || _nSetupErr));
|
|
16001
16017
|
}
|
|
16002
16018
|
|
|
16019
|
+
// \u2500\u2500 COHERE distributed inference handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
16020
|
+
// Subscribe to nexus.cohere.query, process through local Ollama,
|
|
16021
|
+
// publish response to nexus.cohere.response.
|
|
16022
|
+
// Privacy: handler constructs ISOLATED messages \u2014 no history, no system prompt.
|
|
16023
|
+
if (_natsConn && _natsCodec) {
|
|
16024
|
+
const _cohereSub = _natsConn.subscribe('nexus.cohere.query');
|
|
16025
|
+
(async function() {
|
|
16026
|
+
for await (const _cMsg of _cohereSub) {
|
|
16027
|
+
if (!cohereActive) continue;
|
|
16028
|
+
try {
|
|
16029
|
+
const _cData = JSON.parse(_natsCodec.decode(_cMsg.data));
|
|
16030
|
+
if (!_cData.queryId || !_cData.query) continue;
|
|
16031
|
+
// Dedup: skip if we already processed this queryId
|
|
16032
|
+
if (cohereDedup.has(_cData.queryId)) continue;
|
|
16033
|
+
cohereDedup.set(_cData.queryId, Date.now());
|
|
16034
|
+
// Prune dedup map (60s TTL)
|
|
16035
|
+
const _cNow = Date.now();
|
|
16036
|
+
for (const [_cK, _cV] of cohereDedup) { if (_cNow - _cV > 60000) cohereDedup.delete(_cK); }
|
|
16037
|
+
// Random jitter 0-2s to prevent all nodes racing
|
|
16038
|
+
await new Promise(function(r) { setTimeout(r, Math.random() * 2000); });
|
|
16039
|
+
// Skip if another node already responded (check dedup again after jitter)
|
|
16040
|
+
if (!cohereActive) continue;
|
|
16041
|
+
dlog('COHERE query: ' + _cData.queryId + ' \u2014 ' + (_cData.query || '').slice(0, 80));
|
|
16042
|
+
const _cStart = Date.now();
|
|
16043
|
+
// Query local Ollama \u2014 ISOLATED context (no history, no system prompt)
|
|
16044
|
+
const _cOllamaUrl = process.env.OLLAMA_HOST || 'http://localhost:11434';
|
|
16045
|
+
let _cModel = '';
|
|
16046
|
+
try {
|
|
16047
|
+
const _cTags = await fetch(_cOllamaUrl + '/api/tags').then(function(r) { return r.json(); });
|
|
16048
|
+
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 : '';
|
|
16051
|
+
} catch {}
|
|
16052
|
+
if (!_cModel) { dlog('COHERE: no Ollama models available'); continue; }
|
|
16053
|
+
try {
|
|
16054
|
+
const _cResp = await fetch(_cOllamaUrl + '/api/chat', {
|
|
16055
|
+
method: 'POST',
|
|
16056
|
+
headers: { 'Content-Type': 'application/json' },
|
|
16057
|
+
body: JSON.stringify({
|
|
16058
|
+
model: _cModel,
|
|
16059
|
+
messages: [{ role: 'user', content: _cData.query }],
|
|
16060
|
+
stream: false,
|
|
16061
|
+
}),
|
|
16062
|
+
signal: AbortSignal.timeout(120000),
|
|
16063
|
+
});
|
|
16064
|
+
const _cResult = await _cResp.json();
|
|
16065
|
+
const _cContent = _cResult.message ? _cResult.message.content : '';
|
|
16066
|
+
const _cLatency = Date.now() - _cStart;
|
|
16067
|
+
// Sign response for accountability (HMAC-SHA256 with peerId)
|
|
16068
|
+
const _cSigData = _cData.queryId + ':' + _cContent.slice(0, 200) + ':' + _cModel + ':' + _cLatency;
|
|
16069
|
+
const _cSig = require('crypto').createHmac('sha256', nexus.peerId).update(_cSigData).digest('hex').slice(0, 32);
|
|
16070
|
+
// Scan inbound query for leaked secrets (defense-in-depth)
|
|
16071
|
+
const _cSecretPatterns = [/sk-[a-zA-Z0-9]{20,}/g, /ghp_[a-zA-Z0-9]{36,}/g, /AKIA[0-9A-Z]{16}/g];
|
|
16072
|
+
for (const _cPat of _cSecretPatterns) {
|
|
16073
|
+
if (_cPat.test(_cData.query)) { dlog('COHERE WARNING: inbound query contains potential secret!'); break; }
|
|
16074
|
+
}
|
|
16075
|
+
// Publish response
|
|
16076
|
+
_natsConn.publish('nexus.cohere.response', _natsCodec.encode(JSON.stringify({
|
|
16077
|
+
type: 'cohere.response',
|
|
16078
|
+
queryId: _cData.queryId,
|
|
16079
|
+
content: _cContent,
|
|
16080
|
+
model: _cModel,
|
|
16081
|
+
provider: nexus.peerId,
|
|
16082
|
+
agentName: nexus.agentName || ('oa-' + require('os').hostname().slice(0, 12)),
|
|
16083
|
+
latencyMs: _cLatency,
|
|
16084
|
+
usage: _cResult.eval_count ? { inputTokens: _cResult.prompt_eval_count || 0, outputTokens: _cResult.eval_count || 0 } : undefined,
|
|
16085
|
+
signature: _cSig,
|
|
16086
|
+
})));
|
|
16087
|
+
dlog('COHERE response: ' + _cData.queryId + ' model=' + _cModel + ' ' + _cLatency + 'ms');
|
|
16088
|
+
} catch (_cErr) {
|
|
16089
|
+
dlog('COHERE inference error: ' + (_cErr.message || _cErr));
|
|
16090
|
+
}
|
|
16091
|
+
} catch (_cParseErr) {
|
|
16092
|
+
// Malformed message \u2014 skip
|
|
16093
|
+
}
|
|
16094
|
+
}
|
|
16095
|
+
})().catch(function(e) { dlog('COHERE query handler loop error: ' + (e.message || e)); });
|
|
16096
|
+
dlog('COHERE query handler subscribed to nexus.cohere.query');
|
|
16097
|
+
}
|
|
16098
|
+
|
|
16003
16099
|
writeStatus();
|
|
16004
16100
|
console.log('Nexus daemon connected as ' + nexus.peerId);
|
|
16005
16101
|
} catch (err) {
|
|
@@ -16065,9 +16161,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
16065
16161
|
"budget_set",
|
|
16066
16162
|
"spend",
|
|
16067
16163
|
"remote_infer",
|
|
16068
|
-
"cohere_status"
|
|
16164
|
+
"cohere_status",
|
|
16165
|
+
"cohere_enable",
|
|
16166
|
+
"cohere_disable"
|
|
16069
16167
|
],
|
|
16070
|
-
description: "The nexus action. MUST call 'connect' first (spawns daemon). Then: join_room, send_message, discover_peers, expose, status, cohere_status, etc."
|
|
16168
|
+
description: "The nexus action. MUST call 'connect' first (spawns daemon). Then: join_room, send_message, discover_peers, expose, status, cohere_status, cohere_enable, cohere_disable, etc."
|
|
16071
16169
|
},
|
|
16072
16170
|
room_id: {
|
|
16073
16171
|
type: "string",
|
|
@@ -16280,6 +16378,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
16280
16378
|
case "cohere_status":
|
|
16281
16379
|
result = await this.doCohereSummary();
|
|
16282
16380
|
break;
|
|
16381
|
+
case "cohere_enable":
|
|
16382
|
+
result = await this.sendDaemonCmd("cohere_enable", {});
|
|
16383
|
+
break;
|
|
16384
|
+
case "cohere_disable":
|
|
16385
|
+
result = await this.sendDaemonCmd("cohere_disable", {});
|
|
16386
|
+
break;
|
|
16283
16387
|
default:
|
|
16284
16388
|
return { success: false, output: "", error: `Unknown nexus action: ${action}`, durationMs: Date.now() - start };
|
|
16285
16389
|
}
|
|
@@ -44638,6 +44742,9 @@ var init_banner = __esm({
|
|
|
44638
44742
|
const row = frame.grid[r];
|
|
44639
44743
|
if (!row)
|
|
44640
44744
|
continue;
|
|
44745
|
+
if (r === 1 && this.currentDesign?.type === "default") {
|
|
44746
|
+
buf += `\x1B]8;;file://${process.cwd()}\x07`;
|
|
44747
|
+
}
|
|
44641
44748
|
let prevFg = -1, prevBg = -1, prevBold = false;
|
|
44642
44749
|
for (let c3 = 0; c3 < Math.min(this.width, row.length); c3++) {
|
|
44643
44750
|
const cell = row[c3];
|
|
@@ -44657,6 +44764,9 @@ var init_banner = __esm({
|
|
|
44657
44764
|
buf += seq + cell.char;
|
|
44658
44765
|
}
|
|
44659
44766
|
buf += "\x1B[0m";
|
|
44767
|
+
if (r === 1 && this.currentDesign?.type === "default") {
|
|
44768
|
+
buf += "\x1B]8;;\x07";
|
|
44769
|
+
}
|
|
44660
44770
|
}
|
|
44661
44771
|
buf += "\x1B8";
|
|
44662
44772
|
process.stdout.write(buf);
|
|
@@ -52215,7 +52325,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
52215
52325
|
* before readline splits them into garbage text. Scroll wheel support
|
|
52216
52326
|
* is keyboard-only (Page Up/Down, Shift+Up/Down).
|
|
52217
52327
|
*/
|
|
52218
|
-
hookReadlineScroll(rl, onEscape) {
|
|
52328
|
+
hookReadlineScroll(rl, onEscape, onCtrlO) {
|
|
52219
52329
|
if (!rl || !rl._ttyWrite)
|
|
52220
52330
|
return;
|
|
52221
52331
|
const self = this;
|
|
@@ -52233,6 +52343,10 @@ ${CONTENT_BG_SEQ}`);
|
|
|
52233
52343
|
if (cursor <= 0)
|
|
52234
52344
|
return;
|
|
52235
52345
|
}
|
|
52346
|
+
if (key?.ctrl && key?.name === "o" && onCtrlO) {
|
|
52347
|
+
onCtrlO();
|
|
52348
|
+
return;
|
|
52349
|
+
}
|
|
52236
52350
|
if (s && (/\x1B\[</.test(s) || /^\d+;\d+;\d*[Mm]/.test(s) || /^;\d+[Mm]/.test(s) || /\[<\d/.test(s))) {
|
|
52237
52351
|
return;
|
|
52238
52352
|
}
|
|
@@ -54083,6 +54197,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
54083
54197
|
let _escapeHandler = null;
|
|
54084
54198
|
statusBar.hookReadlineScroll(rl, () => {
|
|
54085
54199
|
_escapeHandler?.();
|
|
54200
|
+
}, () => {
|
|
54201
|
+
if (sudoPromptPending) {
|
|
54202
|
+
passwordShowPlain = !passwordShowPlain;
|
|
54203
|
+
if (statusBar.isActive)
|
|
54204
|
+
statusBar.handleResize();
|
|
54205
|
+
}
|
|
54086
54206
|
});
|
|
54087
54207
|
rl.output = null;
|
|
54088
54208
|
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
@@ -54337,6 +54457,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
54337
54457
|
}
|
|
54338
54458
|
})().catch(() => {
|
|
54339
54459
|
});
|
|
54460
|
+
let passwordShowPlain = false;
|
|
54340
54461
|
function handleSudoRequest(_command) {
|
|
54341
54462
|
if (sudoPromptPending)
|
|
54342
54463
|
return;
|
|
@@ -54345,12 +54466,20 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
54345
54466
|
return;
|
|
54346
54467
|
}
|
|
54347
54468
|
sudoPromptPending = true;
|
|
54348
|
-
|
|
54349
|
-
|
|
54350
|
-
|
|
54351
|
-
|
|
54352
|
-
|
|
54469
|
+
writeContent(() => renderInfo("Password required for sudo. Type below, Enter to submit. Ctrl+O to show/hide."));
|
|
54470
|
+
const pwPrompt = `\x1B[38;5;178m\u{1F511}\x1B[0m `;
|
|
54471
|
+
rl.setPrompt(pwPrompt);
|
|
54472
|
+
if (statusBar.isActive) {
|
|
54473
|
+
const origProvider = statusBar.inputStateProvider;
|
|
54474
|
+
statusBar.inputStateProvider = () => {
|
|
54475
|
+
const state = origProvider?.() ?? { line: "", cursor: 0 };
|
|
54476
|
+
if (passwordShowPlain)
|
|
54477
|
+
return state;
|
|
54478
|
+
return { line: "\u25CF".repeat(state.line.length), cursor: state.cursor };
|
|
54479
|
+
};
|
|
54480
|
+
statusBar.setPromptText(pwPrompt, 3);
|
|
54353
54481
|
}
|
|
54482
|
+
showPrompt();
|
|
54354
54483
|
}
|
|
54355
54484
|
async function handleAskUser(question, options, allowMultiple) {
|
|
54356
54485
|
if (statusBar?.isActive)
|
|
@@ -54586,6 +54715,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
54586
54715
|
statusBar.setCohereActive(cohereEnabled);
|
|
54587
54716
|
saveProjectSettings(repoRoot, { cohere: cohereEnabled });
|
|
54588
54717
|
saveGlobalSettings({ cohere: cohereEnabled });
|
|
54718
|
+
try {
|
|
54719
|
+
const { NexusTool: NexusTool2 } = __require("../../execution/dist/tools/nexus.js");
|
|
54720
|
+
const nexusTool = new NexusTool2(repoRoot);
|
|
54721
|
+
nexusTool.execute({ action: cohereEnabled ? "cohere_enable" : "cohere_disable" }).catch(() => {
|
|
54722
|
+
});
|
|
54723
|
+
} catch {
|
|
54724
|
+
}
|
|
54589
54725
|
return cohereEnabled;
|
|
54590
54726
|
},
|
|
54591
54727
|
isCohere() {
|
|
@@ -55686,28 +55822,26 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
55686
55822
|
async function processLine(input) {
|
|
55687
55823
|
if (depSudoPromptPending && depSudoResolver) {
|
|
55688
55824
|
const pw = input.trim();
|
|
55689
|
-
|
|
55690
|
-
|
|
55691
|
-
|
|
55692
|
-
|
|
55693
|
-
}
|
|
55694
|
-
|
|
55695
|
-
}
|
|
55825
|
+
passwordShowPlain = false;
|
|
55826
|
+
statusBar.setInputStateProvider(() => ({
|
|
55827
|
+
line: rl.line ?? "",
|
|
55828
|
+
cursor: rl.cursor ?? 0
|
|
55829
|
+
}));
|
|
55830
|
+
writeContent(() => renderInfo("\u{1F511} Password received"));
|
|
55696
55831
|
depSudoResolver(pw || null);
|
|
55697
55832
|
showPrompt();
|
|
55698
55833
|
return;
|
|
55699
55834
|
}
|
|
55700
55835
|
if (sudoPromptPending && activeTask) {
|
|
55701
55836
|
sudoPromptPending = false;
|
|
55837
|
+
passwordShowPlain = false;
|
|
55702
55838
|
sessionSudoPassword = input;
|
|
55703
55839
|
activeTask.runner.setSudoPassword(input);
|
|
55704
|
-
|
|
55705
|
-
|
|
55706
|
-
|
|
55707
|
-
|
|
55708
|
-
}
|
|
55709
|
-
process.stdout.write(pwRecvMsg2);
|
|
55710
|
-
}
|
|
55840
|
+
statusBar.setInputStateProvider(() => ({
|
|
55841
|
+
line: rl.line ?? "",
|
|
55842
|
+
cursor: rl.cursor ?? 0
|
|
55843
|
+
}));
|
|
55844
|
+
writeContent(() => renderInfo("\u{1F511} Password received"));
|
|
55711
55845
|
showPrompt();
|
|
55712
55846
|
return;
|
|
55713
55847
|
}
|
package/package.json
CHANGED