open-agents-ai 0.103.42 → 0.103.44
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 +85 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12297,9 +12297,9 @@ async function handleCmd(cmd) {
|
|
|
12297
12297
|
if (!peerId) { writeResp(id, { ok: false, output: 'target_peer is required' }); return; }
|
|
12298
12298
|
dlog('invoke_capability: peer=' + peerId.slice(0, 20) + ' cap=' + capability);
|
|
12299
12299
|
try {
|
|
12300
|
-
// Wrap in a
|
|
12301
|
-
const INVOKE_TIMEOUT =
|
|
12302
|
-
const invokePromise = nexus.invokeCapability(peerId, capability, typeof input === 'string' ? { prompt: input } : input, { stream: false, maxDurationMs:
|
|
12300
|
+
// Wrap in a 300s timeout \u2014 remote API inference (Chutes, etc.) can take 60-180s for large models
|
|
12301
|
+
const INVOKE_TIMEOUT = 300_000;
|
|
12302
|
+
const invokePromise = nexus.invokeCapability(peerId, capability, typeof input === 'string' ? { prompt: input } : input, { stream: false, maxDurationMs: 240000 });
|
|
12303
12303
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('invoke_capability timed out after ' + (INVOKE_TIMEOUT / 1000) + 's (client-side timeout)')), INVOKE_TIMEOUT));
|
|
12304
12304
|
const result = await Promise.race([invokePromise, timeoutPromise]);
|
|
12305
12305
|
dlog('invoke_capability: SUCCESS');
|
|
@@ -12349,8 +12349,8 @@ async function handleCmd(cmd) {
|
|
|
12349
12349
|
// Direct invoke on specified peer
|
|
12350
12350
|
dlog('remote_infer: invoking ' + riCapName + ' on explicit peer ' + riTargetPeer.slice(0, 20));
|
|
12351
12351
|
try {
|
|
12352
|
-
var RI_TIMEOUT =
|
|
12353
|
-
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: false, maxDurationMs:
|
|
12352
|
+
var RI_TIMEOUT = 300000; // 5 min \u2014 remote APIs (Chutes, etc.) can be slow for large models
|
|
12353
|
+
var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: false, maxDurationMs: 240000 });
|
|
12354
12354
|
var riTimeoutP = new Promise(function(_, reject) { setTimeout(function() { reject(new Error('remote_infer timed out after ' + (RI_TIMEOUT / 1000) + 's')); }, RI_TIMEOUT); });
|
|
12355
12355
|
var riResult = await Promise.race([riInvokeP, riTimeoutP]);
|
|
12356
12356
|
dlog('remote_infer: SUCCESS (explicit peer)');
|
|
@@ -12378,8 +12378,8 @@ async function handleCmd(cmd) {
|
|
|
12378
12378
|
var rPid = riCandidates[ri];
|
|
12379
12379
|
dlog('remote_infer: trying peer ' + rPid.slice(0, 20) + '...');
|
|
12380
12380
|
try {
|
|
12381
|
-
var PEER_INVOKE_TIMEOUT =
|
|
12382
|
-
var specInvoke = nexus.invokeCapability(rPid, riCapName, riData, { stream: false, maxDurationMs:
|
|
12381
|
+
var PEER_INVOKE_TIMEOUT = 180000; // 3 min per peer \u2014 remote API inference can be slow
|
|
12382
|
+
var specInvoke = nexus.invokeCapability(rPid, riCapName, riData, { stream: false, maxDurationMs: 150000 });
|
|
12383
12383
|
var specTimeout = new Promise(function(_, reject) {
|
|
12384
12384
|
setTimeout(function() { reject(new Error('peer invoke timeout')); }, PEER_INVOKE_TIMEOUT);
|
|
12385
12385
|
});
|
|
@@ -12698,7 +12698,7 @@ async function handleCmd(cmd) {
|
|
|
12698
12698
|
} catch { /* offline \u2014 use zero rates */ }
|
|
12699
12699
|
|
|
12700
12700
|
// Build pricing menu \u2014 match local models to market rates
|
|
12701
|
-
const margin = parseFloat(args.margin || '0
|
|
12701
|
+
const margin = parseFloat(args.margin || '0'); // default free \u2014 set margin > 0 to enable x402 pricing
|
|
12702
12702
|
const pricingMenu = [];
|
|
12703
12703
|
|
|
12704
12704
|
for (const model of models) {
|
|
@@ -12754,6 +12754,16 @@ async function handleCmd(cmd) {
|
|
|
12754
12754
|
const logFile = join(invocationsDir, Date.now() + '-' + capName + '.json');
|
|
12755
12755
|
try { writeFileSync(logFile, JSON.stringify(logEntry, null, 2)); } catch {}
|
|
12756
12756
|
|
|
12757
|
+
// Safe stream write \u2014 consumer may have timed out and closed the stream
|
|
12758
|
+
var streamClosed = false;
|
|
12759
|
+
async function swrite(msg) {
|
|
12760
|
+
if (streamClosed) return;
|
|
12761
|
+
try { await stream.write(msg); } catch (swErr) {
|
|
12762
|
+
dlog('stream.write failed (consumer likely timed out): ' + (swErr.message || swErr));
|
|
12763
|
+
streamClosed = true;
|
|
12764
|
+
}
|
|
12765
|
+
}
|
|
12766
|
+
|
|
12757
12767
|
// Collect input via stream data events
|
|
12758
12768
|
// NOTE: auth_key arrives in invoke.chunk data, NOT in invoke.open (request).
|
|
12759
12769
|
// We must accept + read data FIRST, then validate auth.
|
|
@@ -12771,7 +12781,7 @@ async function handleCmd(cmd) {
|
|
|
12771
12781
|
});
|
|
12772
12782
|
|
|
12773
12783
|
// Accept the invocation so the consumer sends data
|
|
12774
|
-
await
|
|
12784
|
+
await swrite({
|
|
12775
12785
|
type: 'invoke.accept', version: 1,
|
|
12776
12786
|
requestId: request.requestId, accepted: true,
|
|
12777
12787
|
});
|
|
@@ -12802,9 +12812,9 @@ async function handleCmd(cmd) {
|
|
|
12802
12812
|
}
|
|
12803
12813
|
if (reqAuthKey !== exposeAuthKey) {
|
|
12804
12814
|
dlog('expose: auth REJECTED for ' + capName + ' from ' + (request.from || 'unknown'));
|
|
12805
|
-
await
|
|
12806
|
-
await
|
|
12807
|
-
stream.close();
|
|
12815
|
+
await swrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized \u2014 invalid or missing auth key' });
|
|
12816
|
+
await swrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
12817
|
+
try { stream.close(); } catch {}
|
|
12808
12818
|
return;
|
|
12809
12819
|
}
|
|
12810
12820
|
dlog('expose: auth OK for ' + capName);
|
|
@@ -12837,6 +12847,7 @@ async function handleCmd(cmd) {
|
|
|
12837
12847
|
method: 'POST',
|
|
12838
12848
|
headers: chatHeaders,
|
|
12839
12849
|
body: JSON.stringify(chatBody),
|
|
12850
|
+
signal: AbortSignal.timeout(210000), // 3.5 min \u2014 upstream API may be slow
|
|
12840
12851
|
});
|
|
12841
12852
|
genData = await genResp.json();
|
|
12842
12853
|
dlog('expose: ollama response keys=' + Object.keys(genData).join(',') + ' choices=' + (genData.choices ? genData.choices.length : 0));
|
|
@@ -12879,6 +12890,7 @@ async function handleCmd(cmd) {
|
|
|
12879
12890
|
messages: [{ role: 'user', content: flatPrompt }],
|
|
12880
12891
|
stream: false,
|
|
12881
12892
|
}),
|
|
12893
|
+
signal: AbortSignal.timeout(210000), // 3.5 min
|
|
12882
12894
|
});
|
|
12883
12895
|
genData = await genResp.json();
|
|
12884
12896
|
var ptChoices = genData.choices || [];
|
|
@@ -12905,6 +12917,7 @@ async function handleCmd(cmd) {
|
|
|
12905
12917
|
prompt: flatPrompt,
|
|
12906
12918
|
stream: false,
|
|
12907
12919
|
}),
|
|
12920
|
+
signal: AbortSignal.timeout(210000), // 3.5 min
|
|
12908
12921
|
});
|
|
12909
12922
|
genData = await genResp.json();
|
|
12910
12923
|
output = genData.response || '';
|
|
@@ -12920,14 +12933,14 @@ async function handleCmd(cmd) {
|
|
|
12920
12933
|
}
|
|
12921
12934
|
|
|
12922
12935
|
// Stream result back
|
|
12923
|
-
await
|
|
12936
|
+
await swrite({
|
|
12924
12937
|
type: 'invoke.event', version: 1,
|
|
12925
12938
|
requestId: request.requestId, seq: 0,
|
|
12926
12939
|
event: 'result',
|
|
12927
12940
|
data: JSON.stringify(responsePayload),
|
|
12928
12941
|
});
|
|
12929
12942
|
|
|
12930
|
-
await
|
|
12943
|
+
await swrite({
|
|
12931
12944
|
type: 'invoke.done', version: 1,
|
|
12932
12945
|
requestId: request.requestId,
|
|
12933
12946
|
usage: {
|
|
@@ -12937,18 +12950,19 @@ async function handleCmd(cmd) {
|
|
|
12937
12950
|
},
|
|
12938
12951
|
});
|
|
12939
12952
|
} catch (e) {
|
|
12940
|
-
|
|
12953
|
+
dlog('expose: inference error: ' + (e.message || e));
|
|
12954
|
+
await swrite({
|
|
12941
12955
|
type: 'invoke.event', version: 1,
|
|
12942
12956
|
requestId: request.requestId, seq: 0,
|
|
12943
12957
|
event: 'error', data: 'Inference failed: ' + e.message,
|
|
12944
12958
|
});
|
|
12945
|
-
await
|
|
12959
|
+
await swrite({
|
|
12946
12960
|
type: 'invoke.done', version: 1,
|
|
12947
12961
|
requestId: request.requestId,
|
|
12948
12962
|
usage: { inputBytes: 0, outputBytes: 0 },
|
|
12949
12963
|
});
|
|
12950
12964
|
}
|
|
12951
|
-
stream.close();
|
|
12965
|
+
try { stream.close(); } catch {}
|
|
12952
12966
|
}, capOpts);
|
|
12953
12967
|
}
|
|
12954
12968
|
}
|
|
@@ -13347,7 +13361,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13347
13361
|
},
|
|
13348
13362
|
margin: {
|
|
13349
13363
|
type: "string",
|
|
13350
|
-
description: "Price margin multiplier for expose (0.5 = 50% of market rate, 0 = free). Default: 0
|
|
13364
|
+
description: "Price margin multiplier for expose (0.5 = 50% of market rate, 0 = free). Default: 0 (free)"
|
|
13351
13365
|
},
|
|
13352
13366
|
daily_limit: {
|
|
13353
13367
|
type: "string",
|
|
@@ -13700,6 +13714,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13700
13714
|
}
|
|
13701
13715
|
}
|
|
13702
13716
|
}
|
|
13717
|
+
await this.ensureWallet();
|
|
13703
13718
|
const daemonPath = join30(this.nexusDir, "nexus-daemon.mjs");
|
|
13704
13719
|
await writeFile12(daemonPath, DAEMON_SCRIPT);
|
|
13705
13720
|
const agentName = args.agent_name || "open-agents-node";
|
|
@@ -14016,6 +14031,57 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14016
14031
|
`Free inference (margin=0) works without funding.`
|
|
14017
14032
|
].join("\n");
|
|
14018
14033
|
}
|
|
14034
|
+
/**
|
|
14035
|
+
* Auto-create wallet + x402-wallet.key if none exists.
|
|
14036
|
+
* Called from doConnect() before daemon spawn so the daemon starts x402-ready.
|
|
14037
|
+
* Silent — no user output, just ensures the files exist.
|
|
14038
|
+
*/
|
|
14039
|
+
async ensureWallet() {
|
|
14040
|
+
const walletPath = join30(this.nexusDir, "wallet.enc");
|
|
14041
|
+
if (existsSync23(walletPath))
|
|
14042
|
+
return;
|
|
14043
|
+
let address;
|
|
14044
|
+
let privKeyHex;
|
|
14045
|
+
try {
|
|
14046
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
14047
|
+
const privKey = randomBytes6(32);
|
|
14048
|
+
privKeyHex = privKey.toString("hex");
|
|
14049
|
+
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
14050
|
+
address = account.address;
|
|
14051
|
+
privKey.fill(0);
|
|
14052
|
+
} catch {
|
|
14053
|
+
const privKey = randomBytes6(32);
|
|
14054
|
+
privKeyHex = privKey.toString("hex");
|
|
14055
|
+
address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
14056
|
+
privKey.fill(0);
|
|
14057
|
+
}
|
|
14058
|
+
const salt = randomBytes6(32);
|
|
14059
|
+
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
14060
|
+
const iv = randomBytes6(16);
|
|
14061
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
14062
|
+
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
14063
|
+
enc += cipher.final("hex");
|
|
14064
|
+
const x402KeyPath = join30(this.nexusDir, "x402-wallet.key");
|
|
14065
|
+
const x402Fh = await fsOpen(x402KeyPath, "w", 384);
|
|
14066
|
+
await x402Fh.writeFile("0x" + privKeyHex);
|
|
14067
|
+
await x402Fh.close();
|
|
14068
|
+
privKeyHex = "0".repeat(64);
|
|
14069
|
+
const w = {
|
|
14070
|
+
version: 2,
|
|
14071
|
+
address,
|
|
14072
|
+
encryptedKey: enc,
|
|
14073
|
+
iv: iv.toString("hex"),
|
|
14074
|
+
authTag: cipher.getAuthTag().toString("hex"),
|
|
14075
|
+
salt: salt.toString("hex"),
|
|
14076
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14077
|
+
network: "base",
|
|
14078
|
+
chainId: 8453
|
|
14079
|
+
};
|
|
14080
|
+
const walletFh = await fsOpen(walletPath, "w", 384);
|
|
14081
|
+
await walletFh.writeFile(JSON.stringify(w, null, 2));
|
|
14082
|
+
await walletFh.close();
|
|
14083
|
+
await this.ensureDefaultBudget();
|
|
14084
|
+
}
|
|
14019
14085
|
// ---------------------------------------------------------------------------
|
|
14020
14086
|
// Step 2: USDC Balance Query via Base RPC
|
|
14021
14087
|
// ---------------------------------------------------------------------------
|
|
@@ -28484,7 +28550,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
28484
28550
|
}
|
|
28485
28551
|
this._targetUrl = options.targetUrl ?? DEFAULT_TARGETS[options.kind];
|
|
28486
28552
|
this._stateDir = options.stateDir ?? null;
|
|
28487
|
-
this._margin = options.margin ?? 0
|
|
28553
|
+
this._margin = options.margin ?? 0;
|
|
28488
28554
|
this._passthrough = options.passthrough ?? false;
|
|
28489
28555
|
this._loadbalance = options.loadbalance ?? false;
|
|
28490
28556
|
this._endpointAuth = options.endpointAuth;
|
package/package.json
CHANGED